From b1f2f3f2045de0a6aaee8826794a1e8fb4ce3f5b Mon Sep 17 00:00:00 2001
From: molsonkiko <46202915+molsonkiko@users.noreply.github.com>
Date: Wed, 17 Apr 2024 18:11:34 -0700
Subject: [PATCH] fix error form crash bug; add syntax check command ADDED: 1.
"Check JSON syntax now" command. FIXED: 1. Bug where opening error form could
sometimes cause Notepad++ to crash if the `auto_validate` setting was
true. CHANGED: 1. Made it so that reloading the error form by pressing
`Enter` would not cause certain message boxes to appear, to eliminate a
potential "infinite" loop where the user would hit `Enter` to close the
message box, and that moved focus back to the error form, which then
repeated the cycle when they lifted the `Enter` key.
---
CHANGELOG.md | 13 +-
JsonToolsNppPlugin/Forms/ErrorForm.cs | 8 +-
JsonToolsNppPlugin/Main.cs | 116 ++++++++++++------
.../PluginInfrastructure/NotepadPPGateway.cs | 8 +-
JsonToolsNppPlugin/Properties/AssemblyInfo.cs | 4 +-
docs/README.md | 10 +-
most recent errors.txt | 82 ++++++-------
7 files changed, 150 insertions(+), 91 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b26cee..719c719 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -52,10 +52,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## [7.2.0] - (UNRELEASED) YYYY-MM-DD
+### Added
+
+1. [`Check JSON syntax now` command](/docs/README.md#check-json-syntax-now).
+
+### Changed
+
+1. Made it so that reloading the [error form](/docs/README.md#error-form-and-status-bar) by pressing `Enter` would not cause certain message boxes to appear, to eliminate a potential "infinite" loop where the user would hit `Enter` to close the message box, and that moved focus back to the error form, which then repeated the cycle when they lifted the `Enter` key.
+
### Fixed
-1. Minor bug in [PPrint remembering comments](/docs/README.md#remember_comments) algorithm implementation that caused some arrays and objects to be compressed when they should have been pretty-printed.
-2. Fix bug where tests could crash under some circumstances due to filesystem weirdness making it impossible to find test files.
+1. Bug where opening error form could sometimes cause Notepad++ to crash if the [`auto_validate` setting](/docs/README.md#automatically-check-for-errors-after-editing) was true.
+2. Minor bug in [PPrint remembering comments](/docs/README.md#remember_comments) algorithm implementation that caused some arrays and objects to be compressed when they should have been pretty-printed.
+3. Fix bug where tests could crash under some circumstances due to filesystem weirdness making it impossible to find test files.
## [7.1.0] - 2024-02-28
diff --git a/JsonToolsNppPlugin/Forms/ErrorForm.cs b/JsonToolsNppPlugin/Forms/ErrorForm.cs
index 5f54dc9..86a3e73 100644
--- a/JsonToolsNppPlugin/Forms/ErrorForm.cs
+++ b/JsonToolsNppPlugin/Forms/ErrorForm.cs
@@ -181,19 +181,25 @@ private void ErrorForm_KeyUp(object sender, KeyEventArgs e)
{
// refresh error form based on current contents of current file
e.Handled = true;
+ Main.errorFormTriggeredParse = true;
// temporarily turn off offer_to_show_lint prompt, because the user obviously wants to see it
bool previousOfferToShowLint = Main.settings.offer_to_show_lint;
Main.settings.offer_to_show_lint = false;
Main.TryParseJson(preferPreviousDocumentType:true);
- Main.settings.offer_to_show_lint = previousOfferToShowLint;
if (Main.TryGetInfoForFile(Main.activeFname, out JsonFileInfo info)
&& info.lints != null)
{
if (info.filenameOfMostRecentValidatingSchema is null)
Reload(Main.activeFname, info.lints);
else
+ {
Main.ValidateJson(info.filenameOfMostRecentValidatingSchema, false);
+ if (Main.TryGetInfoForFile(Main.activeFname, out info) && info.lints != null && info.statusBarSection != null && info.statusBarSection.Contains("fatal errors"))
+ Reload(Main.activeFname, info.lints);
+ }
}
+ Main.settings.offer_to_show_lint = previousOfferToShowLint;
+ Main.errorFormTriggeredParse = false;
return;
}
else if (e.KeyCode == Keys.Escape)
diff --git a/JsonToolsNppPlugin/Main.cs b/JsonToolsNppPlugin/Main.cs
index d6f4d54..a2dbcc3 100644
--- a/JsonToolsNppPlugin/Main.cs
+++ b/JsonToolsNppPlugin/Main.cs
@@ -48,6 +48,16 @@ class Main
public static SortForm sortForm = null;
// error form stuff
public static ErrorForm errorForm = null;
+ ///
+ /// we need this boolean to avoid "infinite" loops as follows:
+ /// 1. The user presses Enter in the error form to parse the document.
+ /// 2. the parse fails
+ /// 3. the user is shown a dialog box warning them that the parse failed.
+ /// 4. the user presses Enter to close the dialog box
+ /// 5. focus returns to the error form
+ /// 6. the user releases the Enter key, triggering the ErrorForm_KeyUp event again and returning to step 1.
+ ///
+ public static bool errorFormTriggeredParse = false;
// regex search to json stuff
public static RegexSearchForm regexSearchForm = null;
// schema auto-validation stuff
@@ -108,32 +118,33 @@ static internal void CommandMenuInit()
PluginBase.SetCommand(2, "&Compress current JSON file", CompressJson, new ShortcutKey(true, true, true, Keys.C)); compressId = 2;
PluginBase.SetCommand(3, "Path to current p&osition", CopyPathToCurrentPosition, new ShortcutKey(true, true, true, Keys.L)); pathToPositionId = 3;
PluginBase.SetCommand(4, "Select every val&id JSON in selection", SelectEveryValidJson);
+ PluginBase.SetCommand(5, "Chec&k JSON syntax now", CheckJsonSyntaxNow);
// Here you insert a separator
- PluginBase.SetCommand(5, "---", null);
- PluginBase.SetCommand(6, "Open &JSON tree viewer", () => OpenJsonTree(), new ShortcutKey(true, true, true, Keys.J)); jsonTreeId = 6;
- PluginBase.SetCommand(7, "&Get JSON from files and APIs", OpenGrepperForm, new ShortcutKey(true, true, true, Keys.G)); grepperFormId = 7;
- PluginBase.SetCommand(8, "Sort arra&ys", OpenSortForm); sortFormId = 8;
- PluginBase.SetCommand(9, "&Settings", OpenSettings, new ShortcutKey(true, true, true, Keys.S));
- PluginBase.SetCommand(10, "---", null);
- PluginBase.SetCommand(11, "&Validate JSON against JSON schema", () => ValidateJson());
- PluginBase.SetCommand(12, "Choose schemas to automatically validate &filename patterns", MapSchemasToFnamePatterns);
- PluginBase.SetCommand(13, "Generate sc&hema from JSON", GenerateJsonSchema);
- PluginBase.SetCommand(14, "Generate &random JSON from schema", GenerateRandomJson);
- PluginBase.SetCommand(15, "---", null);
- PluginBase.SetCommand(16, "Run &tests", async () => await TestRunner.RunAll());
- PluginBase.SetCommand(17, "A&bout", ShowAboutForm); AboutFormId = 17;
- PluginBase.SetCommand(18, "See most recent syntax &errors in this file", () => OpenErrorForm(activeFname, false)); errorFormId = 18;
- PluginBase.SetCommand(19, "JSON to YAML", DumpYaml);
- PluginBase.SetCommand(20, "---", null);
- PluginBase.SetCommand(21, "Parse JSON Li&nes document", () => OpenJsonTree(DocumentType.JSONL));
- PluginBase.SetCommand(22, "&Array to JSON Lines", DumpJsonLines);
- PluginBase.SetCommand(23, "---", null);
- PluginBase.SetCommand(24, "D&ump selected text as JSON string(s)", DumpSelectedTextAsJsonString);
- PluginBase.SetCommand(25, "Dump JSON string(s) as ra&w text", DumpSelectedJsonStringsAsText);
- PluginBase.SetCommand(26, "---", null);
- PluginBase.SetCommand(27, "Open tree for &INI file", () => OpenJsonTree(DocumentType.INI));
- PluginBase.SetCommand(28, "---", null);
- PluginBase.SetCommand(29, "Rege&x search to JSON", RegexSearchToJson);
+ PluginBase.SetCommand(6, "---", null);
+ PluginBase.SetCommand(7, "Open &JSON tree viewer", () => OpenJsonTree(), new ShortcutKey(true, true, true, Keys.J)); jsonTreeId = 7;
+ PluginBase.SetCommand(8, "&Get JSON from files and APIs", OpenGrepperForm, new ShortcutKey(true, true, true, Keys.G)); grepperFormId = 8;
+ PluginBase.SetCommand(9, "Sort arra&ys", OpenSortForm); sortFormId = 9;
+ PluginBase.SetCommand(10, "&Settings", OpenSettings, new ShortcutKey(true, true, true, Keys.S));
+ PluginBase.SetCommand(11, "---", null);
+ PluginBase.SetCommand(12, "&Validate JSON against JSON schema", () => ValidateJson());
+ PluginBase.SetCommand(13, "Choose schemas to automatically validate &filename patterns", MapSchemasToFnamePatterns);
+ PluginBase.SetCommand(14, "Generate sc&hema from JSON", GenerateJsonSchema);
+ PluginBase.SetCommand(15, "Generate &random JSON from schema", GenerateRandomJson);
+ PluginBase.SetCommand(16, "---", null);
+ PluginBase.SetCommand(17, "Run &tests", async () => await TestRunner.RunAll());
+ PluginBase.SetCommand(18, "A&bout", ShowAboutForm); AboutFormId = 18;
+ PluginBase.SetCommand(19, "See most recent syntax &errors in this file", () => OpenErrorForm(activeFname, false)); errorFormId = 19;
+ PluginBase.SetCommand(20, "JSON to YAML", DumpYaml);
+ PluginBase.SetCommand(21, "---", null);
+ PluginBase.SetCommand(22, "Parse JSON Li&nes document", () => OpenJsonTree(DocumentType.JSONL));
+ PluginBase.SetCommand(23, "&Array to JSON Lines", DumpJsonLines);
+ PluginBase.SetCommand(24, "---", null);
+ PluginBase.SetCommand(25, "D&ump selected text as JSON string(s)", DumpSelectedTextAsJsonString);
+ PluginBase.SetCommand(26, "Dump JSON string(s) as ra&w text", DumpSelectedJsonStringsAsText);
+ PluginBase.SetCommand(27, "---", null);
+ PluginBase.SetCommand(28, "Open tree for &INI file", () => OpenJsonTree(DocumentType.INI));
+ PluginBase.SetCommand(29, "---", null);
+ PluginBase.SetCommand(30, "Rege&x search to JSON", RegexSearchToJson);
// write the schema to fname patterns file if it doesn't exist, then parse it
SetSchemasToFnamePatternsFname();
@@ -660,7 +671,9 @@ public static (ParserState parserState, JNode node, bool usesSelections, Documen
else
info.usesSelections |= !noTextSelected;
info.lints = lints;
- if (lintCount > 0 && settings.offer_to_show_lint)
+ ParserState parserStateToSet = fatal ? ParserState.FATAL : jsonParser.state;
+ SetStatusBarSection(parserStateToSet, fname, info, documentType, lintCount);
+ if (lintCount > 0 && settings.offer_to_show_lint && !wasAutotriggered)
{
string msg = $"There were {lintCount} syntax errors in the document. Would you like to see them?\r\n(You can turn off these prompts in the settings (offer_to_show_lint setting))";
if (MessageBox.Show(msg, "View syntax errors in document?", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
@@ -677,13 +690,12 @@ public static (ParserState parserState, JNode node, bool usesSelections, Documen
if (lintCount > 0 && noTextSelected && !wasAutotriggered)
Npp.editor.GoToLegalPos(lints[lintCount - 1].pos);
// unacceptable error, show message box
- MessageBox.Show($"Could not parse the document because of error\n{errorMessage}",
- $"Error while trying to parse {Npp.DocumentTypeSuperTypeName(documentType)}",
- MessageBoxButtons.OK,
- MessageBoxIcon.Error);
+ if (!errorFormTriggeredParse)
+ MessageBox.Show($"Could not parse the document because of error\n{errorMessage}",
+ $"Error while trying to parse {Npp.DocumentTypeSuperTypeName(documentType)}",
+ MessageBoxButtons.OK,
+ MessageBoxIcon.Error);
}
- ParserState parserStateToSet = fatal ? ParserState.FATAL : jsonParser.state;
- SetStatusBarSection(parserStateToSet, fname, info, documentType, lintCount);
if (info.tv != null)
{
info.tv.Invoke(new Action(() =>
@@ -981,6 +993,14 @@ public static JNode RenameAll(Dictionary keyChanges, JO
return obj;
}
+ public static void CheckJsonSyntaxNow()
+ {
+ string curFname = Npp.notepad.GetCurrentFilePath();
+ (ParserState parserState, _, _, _) = TryParseJson(Npp.FileExtension(curFname) == "jsonl" ? DocumentType.JSONL : DocumentType.JSON);
+ if (parserState == ParserState.FATAL)
+ RefreshErrorFormInOwnThread(curFname);
+ }
+
///
/// if there are one or more selections, dump each selection as a JSON string on a separate line.
/// Otherwise just dump the whole document on the same line.
@@ -1251,6 +1271,19 @@ private static void DisplayErrorForm(ErrorForm form)
Npp.notepad.ShowDockingForm(form);
}
+ private static void RefreshErrorFormInOwnThread(string fname)
+ {
+ if (errorForm == null)
+ return;
+ errorForm.Invoke(new Action(() =>
+ {
+ if (errorForm.IsDisposed || !TryGetInfoForFile(fname, out JsonFileInfo info) || info.lints == null)
+ return;
+ errorForm.Reload(fname, info.lints);
+ Npp.editor.GrabFocus();
+ }));
+ }
+
public static void CopyPathToCurrentPosition()
{
int pos = Npp.editor.GetCurrentPos();
@@ -1515,12 +1548,15 @@ static void ShowAboutForm()
/// or if it failed, where the first error was.
/// If ignoreSelections, always validate the entire file even the selected text is valid JSON.
///
- public static void ValidateJson(string schemaPath = null, bool messageOnSuccess = true, bool ignoreSelections = false)
+ public static void ValidateJson(string schemaPath = null, bool messageOnSuccess = true, bool ignoreSelections = false, bool wasAutotriggered = false)
{
- (ParserState parserState, JNode json, _, DocumentType documentType) = TryParseJson(preferPreviousDocumentType:true, ignoreSelections: ignoreSelections);
+ (ParserState parserState, JNode json, _, DocumentType documentType) = TryParseJson(wasAutotriggered: wasAutotriggered, preferPreviousDocumentType:true, ignoreSelections: ignoreSelections);
+ string curFname = Npp.notepad.GetCurrentFilePath();
if (parserState == ParserState.FATAL || json == null)
+ {
+ RefreshErrorFormInOwnThread(curFname);
return;
- string curFname = Npp.notepad.GetCurrentFilePath();
+ }
if (schemaPath == null)
{
FileDialog openFileDialog = new OpenFileDialog();
@@ -1551,8 +1587,7 @@ public static void ValidateJson(string schemaPath = null, bool messageOnSuccess
info.filenameOfMostRecentValidatingSchema = schemaPath;
info.lints = info.lints is null ? problems : info.lints.Concat(problems).ToList();
int lintCount = info.lints.Count;
- if (errorForm != null && !errorForm.IsDisposed)
- errorForm.Invoke(new Action(() => errorForm.Reload(curFname, info.lints)));
+ RefreshErrorFormInOwnThread(curFname);
SetStatusBarSection(parserState, curFname, info, documentType, lintCount);
if (!validates && problems.Count > 0)
{
@@ -1753,7 +1788,7 @@ static void SetSchemasToFnamePatternsFname()
/// if the filename doesn't match, return false.
///
///
- static bool ValidateIfFilenameMatches(string fname, bool wasAutotriggered = false, bool wasTriggeredByParseTimer = false)
+ static bool ValidateIfFilenameMatches(string fname, bool wasAutotriggered = false)
{
if (wasAutotriggered && Npp.editor.GetLength() > Main.settings.max_file_size_MB_slow_actions * 1e6)
return false;
@@ -1765,7 +1800,7 @@ static bool ValidateIfFilenameMatches(string fname, bool wasAutotriggered = fals
var regex = ((JRegex)pat).regex;
if (!regex.IsMatch(fname)) continue;
// the filename matches a pattern for this schema, so we'll try to validate it.
- ValidateJson(schemaFname, false, true);
+ ValidateJson(schemaFname, false, true, wasAutotriggered);
return true;
}
}
@@ -1918,11 +1953,12 @@ private static void DelayedParseAfterEditing(object s)
if ((TryGetInfoForFile(fname, out JsonFileInfo info)
&& (info.documentType == DocumentType.INI || info.documentType == DocumentType.REGEX // file is already being parsed as regex or ini, so stop
|| info.usesSelections)) // file uses selections, so stop (because that could change the user's selections unexpectedly)
- || ValidateIfFilenameMatches(fname, wasTriggeredByParseTimer: true) // if filename is associated with a schema, it will be parsed during the schema validation, so stop
+ || ValidateIfFilenameMatches(fname, true) // if filename is associated with a schema, it will be parsed during the schema validation, so stop
|| !fileExtensionsToAutoParse.Contains(ext)) // extension is not marked for auto-parsing, so stop
return;
// filename matches but it's not associated with a schema or being parsed as non-JSON/JSONL, so just parse normally
TryParseJson(ext == "jsonl" ? DocumentType.JSONL : DocumentType.JSON, true, ignoreSelections:true);
+ RefreshErrorFormInOwnThread(fname);
}
#endregion
}
diff --git a/JsonToolsNppPlugin/PluginInfrastructure/NotepadPPGateway.cs b/JsonToolsNppPlugin/PluginInfrastructure/NotepadPPGateway.cs
index 01569ba..108f470 100644
--- a/JsonToolsNppPlugin/PluginInfrastructure/NotepadPPGateway.cs
+++ b/JsonToolsNppPlugin/PluginInfrastructure/NotepadPPGateway.cs
@@ -170,16 +170,16 @@ public bool SaveCurrentFile()
public void HideDockingForm(System.Windows.Forms.Form form)
{
- Win32.SendMessage(PluginBase.nppData._nppHandle,
+ form.Invoke(new Action(() => Win32.SendMessage(PluginBase.nppData._nppHandle,
(uint)(NppMsg.NPPM_DMMHIDE),
- 0, form.Handle);
+ 0, form.Handle)));
}
public void ShowDockingForm(System.Windows.Forms.Form form)
{
- Win32.SendMessage(PluginBase.nppData._nppHandle,
+ form.Invoke(new Action(() => Win32.SendMessage(PluginBase.nppData._nppHandle,
(uint)(NppMsg.NPPM_DMMSHOW),
- 0, form.Handle);
+ 0, form.Handle)));
}
public Color GetDefaultForegroundColor()
diff --git a/JsonToolsNppPlugin/Properties/AssemblyInfo.cs b/JsonToolsNppPlugin/Properties/AssemblyInfo.cs
index aeef1a0..ddc5924 100644
--- a/JsonToolsNppPlugin/Properties/AssemblyInfo.cs
+++ b/JsonToolsNppPlugin/Properties/AssemblyInfo.cs
@@ -28,5 +28,5 @@
// Build Number
// Revision
//
-[assembly: AssemblyVersion("7.1.0.2")]
-[assembly: AssemblyFileVersion("7.1.0.2")]
+[assembly: AssemblyVersion("7.1.0.3")]
+[assembly: AssemblyFileVersion("7.1.0.3")]
diff --git a/docs/README.md b/docs/README.md
index 85a1ccf..b805cc5 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -248,7 +248,7 @@ The `linting` attribute in Settings enables the built-in linter for the JSON par
About 2 seconds after a not-very-large file (default less than 4 megabytes, configurable in settings) is opened, and after 2 seconds of inactivity following any modification of the file or styling, the plugin can parse the document and performs [JSON Schema validation](#validating-json-against-json-schema) on the document. The user is notified of any errors when this happens, and no further notifications are sent until the user next modifies or re-styles the document.
-This is off by default. If desired, this feature can be turned on in the settings. When turned on, it only applies to files with `json`, `jsonc`, `jsonl`, and `json5` extensions, or files configured for [automatic JSON schema validation](#automatic-validation-of-json-against-json-schema).
+This is off by default. If desired, this feature can be turned on in the settings (`auto_validate` setting). When turned on, it only applies to files with `json`, `jsonc`, `jsonl`, and `json5` extensions, or files configured for [automatic JSON schema validation](#automatic-validation-of-json-against-json-schema).
Prior to [v6.1](/CHANGELOG.md#610---2023-12-28), this automatic validation forced the file to be parsed as JSON. As of v6.1, the document will be parsed as [JSON Lines](#json-lines-documents) if the file extension is `jsonl` and as JSON otherwise. In addition, if the document is already in [regex mode](#regex-search-form) or [ini file mode](#parsing-ini-files), automatic validation is suspended.
@@ -927,6 +927,14 @@ The `toolbar_icons` option in settings lets you customize which toolbar icons sh
Thus, `cot` would give the icon sequence `(compress, path to current position, tree view)`, `P` would give only the pretty-print icon, and `A` would give no icons at all.
+## Check JSON syntax now ##
+
+*Added in version [7.2](/CHANGELOG.md#720---unreleased-yyyy-mm-dd).*
+
+This command checks JSON syntax and updates the [error form and status bar](/docs/README.md#error-form-and-status-bar). It *will not* validate using JSON schema. If there are any [remembered selections](#working-with-selections), it will only parse those selections.
+
+This command will *always* attempt to parse the document as JSON, unless the file extension is `.jsonl`, in which case it will attempt to parse the document as [JSON Lines](#json-lines-documents). This will override [regex mode](#regex-search-form) and [INI mode](#parsing-ini-files).
+
## DSON ##
JSON is not sufficiently [Doge-friendly](https://dogeon.xyz/index.html). This plugin aims to help correct that.
diff --git a/most recent errors.txt b/most recent errors.txt
index 3e8c76e..df27695 100644
--- a/most recent errors.txt
+++ b/most recent errors.txt
@@ -1,4 +1,4 @@
-Test results for JsonTools v7.1.0.2 on Notepad++ 8.6.4 64bit
+Test results for JsonTools v7.1.0.3 on Notepad++ 8.6.4 64bit
NOTE: Ctrl-F (regular expressions *on*) for "Failed [1-9]\d*" to find all failed tests
Tests failed: YAML dumper
=========================
@@ -201,33 +201,33 @@ Testing JsonParser performance
Preview of json: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c"
...
-To convert JSON string of size 89556 into JNode took 3.819 +/- 4.363 ms over 32 trials
-Load times (ms): 2, 3, 3, 3, 4, 27, 2, 2, 5, 2, 2, 2, 3, 1, 1, 5, 2, 2, 2, 3, 2, 2, 6, 2, 2, 2, 3, 1, 1, 5, 2, 1
+To convert JSON string of size 89556 into JNode took 3.582 +/- 3.187 ms over 32 trials
+Load times (ms): 5, 19, 2, 5, 5, 1, 2, 7, 2, 1, 1, 2, 1, 1, 4, 1, 1, 1, 3, 4, 3, 3, 1, 2, 2, 3, 2, 3, 3, 1, 2, 3
=========================
Performance tests for RemesPath (float arithmetic)
=========================
-Compiling query "@[@[:].a * @[:].t < @[:].e]" took 0.086 ms the first time, including approximately 0.097 ms to tokenize the query. Subsequent executions are effectively free due to caching.
-To run pre-compiled query "@[@[:].a * @[:].t < @[:].e]" on JNode from JSON of size 89556 into took 0.058 +/- 0.032 ms over 40 trials
-Query times (ms): 0.12, 0.077, 0.042, 0.042, 0.041, 0.039, 0.04, 0.057, 0.066, 0.053, 0.054, 0.06, 0.052, 0.071, 0.05, 0.056, 0.048, 0.05, 0.049, 0.127, 0.056, 0.095, 0.108, 0.198, 0.062, 0.042, 0.035, 0.03, 0.032, 0.052, 0.034, 0.048, 0.041, 0.031, 0.035, 0.033, 0.073, 0.048, 0.038, 0.03
+Compiling query "@[@[:].a * @[:].t < @[:].e]" took 0.092 ms the first time, including approximately 0.056 ms to tokenize the query. Subsequent executions are effectively free due to caching.
+To run pre-compiled query "@[@[:].a * @[:].t < @[:].e]" on JNode from JSON of size 89556 into took 0.078 +/- 0.303 ms over 40 trials
+Query times (ms): 0.066, 0.034, 0.023, 0.023, 1.969, 0.026, 0.024, 0.026, 0.024, 0.023, 0.023, 0.022, 0.022, 0.024, 0.074, 0.027, 0.023, 0.023, 0.028, 0.029, 0.023, 0.067, 0.037, 0.023, 0.024, 0.029, 0.034, 0.056, 0.032, 0.023, 0.023, 0.029, 0.023, 0.022, 0.022, 0.022, 0.022, 0.023, 0.022, 0.022
Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c"
...
=========================
Performance tests for RemesPath (string operations)
=========================
-Compiling query "@[@[:].z =~ `(?i)[a-z]{5}`]" took 0.066 ms the first time, including approximately 0.074 ms to tokenize the query. Subsequent executions are effectively free due to caching.
-To run pre-compiled query "@[@[:].z =~ `(?i)[a-z]{5}`]" on JNode from JSON of size 89556 into took 0.083 +/- 0.073 ms over 40 trials
-Query times (ms): 0.472, 0.256, 0.178, 0.112, 0.131, 0.055, 0.064, 0.057, 0.055, 0.056, 0.055, 0.055, 0.08, 0.061, 0.061, 0.058, 0.057, 0.056, 0.104, 0.112, 0.079, 0.055, 0.054, 0.053, 0.054, 0.054, 0.062, 0.07, 0.057, 0.067, 0.056, 0.057, 0.055, 0.056, 0.065, 0.071, 0.056, 0.058, 0.056, 0.055
+Compiling query "@[@[:].z =~ `(?i)[a-z]{5}`]" took 0.047 ms the first time, including approximately 0.042 ms to tokenize the query. Subsequent executions are effectively free due to caching.
+To run pre-compiled query "@[@[:].z =~ `(?i)[a-z]{5}`]" on JNode from JSON of size 89556 into took 0.077 +/- 0.113 ms over 40 trials
+Query times (ms): 0.112, 0.063, 0.067, 0.056, 0.055, 0.057, 0.054, 0.779, 0.078, 0.055, 0.056, 0.055, 0.066, 0.072, 0.055, 0.054, 0.08, 0.055, 0.054, 0.055, 0.055, 0.055, 0.055, 0.055, 0.055, 0.056, 0.056, 0.055, 0.055, 0.069, 0.055, 0.055, 0.054, 0.056, 0.055, 0.056, 0.055, 0.054, 0.056, 0.055
Preview of result: [{"A": "\n]o1VQ5t6g", "a": 4710024278, "b": 3268860721, "B": "g4Y7+ew^.v", "C": "NK nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" took 0.238 ms the first time, including approximately 0.36 ms to tokenize the query. Subsequent executions are effectively free due to caching.
+ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" took 0.134 ms the first time, including approximately 0.12 ms to tokenize the query. Subsequent executions are effectively free due to caching.
To run pre-compiled query "var qmask = @[:].q;
var nmax_q = max(@[qmask].n);
var nmax_notq = max(@[not qmask].n);
-ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" on JNode from JSON of size 89556 into took 0.035 +/- 0.026 ms over 40 trials
-Query times (ms): 0.152, 0.039, 0.126, 0.066, 0.028, 0.029, 0.027, 0.032, 0.03, 0.035, 0.03, 0.034, 0.031, 0.035, 0.046, 0.022, 0.03, 0.03, 0.03, 0.034, 0.032, 0.034, 0.028, 0.018, 0.023, 0.026, 0.02, 0.02, 0.016, 0.016, 0.018, 0.019, 0.019, 0.021, 0.033, 0.031, 0.032, 0.031, 0.038, 0.034
+ifelse(nmax_q > nmax_notq, `when q=true, nmax = ` + str(nmax_q), `when q=false, nmax= ` + str(nmax_notq))" on JNode from JSON of size 89556 into took 0.025 +/- 0.054 ms over 40 trials
+Query times (ms): 0.068, 0.018, 0.017, 0.016, 0.016, 0.016, 0.016, 0.016, 0.015, 0.015, 0.015, 0.016, 0.015, 0.015, 0.016, 0.015, 0.015, 0.015, 0.015, 0.357, 0.016, 0.015, 0.015, 0.016, 0.015, 0.016, 0.015, 0.016, 0.015, 0.015, 0.016, 0.015, 0.015, 0.015, 0.016, 0.015, 0.015, 0.015, 0.016, 0.015
Preview of result: "when q=false, nmax= 9830935647.0"
...
=========================
@@ -266,11 +266,11 @@ Performance tests for RemesPath (references to compile-time constant variables)
Compiling query "var X = X;
var onetwo = j`[1, 2]`;
-@[:]->at(@, X)->at(@, onetwo)" took 0.163 ms the first time, including approximately 0.126 ms to tokenize the query. Subsequent executions are effectively free due to caching.
+@[:]->at(@, X)->at(@, onetwo)" took 0.076 ms the first time, including approximately 0.078 ms to tokenize the query. Subsequent executions are effectively free due to caching.
To run pre-compiled query "var X = X;
var onetwo = j`[1, 2]`;
-@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.146 +/- 0.613 ms over 40 trials
-Query times (ms): 0.074, 0.027, 0.013, 0.014, 0.014, 0.013, 0.028, 0.032, 3.941, 0.025, 0.027, 0.169, 0.051, 0.037, 0.024, 0.041, 0.026, 0.026, 0.028, 0.033, 0.027, 0.033, 0.043, 0.031, 0.063, 0.03, 0.025, 0.025, 0.034, 0.079, 0.069, 0.026, 0.026, 0.034, 0.027, 0.542, 0.046, 0.02, 0.013, 0.013
+@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.014 +/- 0.007 ms over 40 trials
+Query times (ms): 0.06, 0.012, 0.013, 0.013, 0.012, 0.012, 0.012, 0.013, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.012, 0.015, 0.019, 0.017, 0.012, 0.012, 0.013, 0.012, 0.012
Preview of result: [[1695727848, 0.287562638736685], [2126430375, 0.00767794129708177], [5310550656, 0.380769772645687], [2519183283, 0.153176220930558], [6610062385, 0.662996225870666], [987168256, 0.924410189999928], [6615003609, 0.917112691225947], [4465232046, 0.684311931851536], [8654414565, 0.631485392105992], [
...
=========================
@@ -279,29 +279,29 @@ Performance tests for RemesPath (references to variables that are not compile-ti
Compiling query "var X = @->`X`;
var onetwo = @{1, 2};
-@[:]->at(@, X)->at(@, onetwo)" took 0.185 ms the first time, including approximately 0.146 ms to tokenize the query. Subsequent executions are effectively free due to caching.
+@[:]->at(@, X)->at(@, onetwo)" took 0.082 ms the first time, including approximately 0.078 ms to tokenize the query. Subsequent executions are effectively free due to caching.
To run pre-compiled query "var X = @->`X`;
var onetwo = @{1, 2};
-@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.035 +/- 0.013 ms over 40 trials
-Query times (ms): 0.108, 0.035, 0.036, 0.035, 0.049, 0.032, 0.058, 0.032, 0.032, 0.03, 0.031, 0.032, 0.032, 0.032, 0.03, 0.037, 0.03, 0.031, 0.031, 0.041, 0.032, 0.03, 0.029, 0.032, 0.032, 0.035, 0.034, 0.035, 0.032, 0.035, 0.033, 0.032, 0.034, 0.033, 0.031, 0.033, 0.032, 0.031, 0.032, 0.032
+@[:]->at(@, X)->at(@, onetwo)" on JNode from JSON of size 89556 into took 0.017 +/- 0.006 ms over 40 trials
+Query times (ms): 0.054, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.017, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.016, 0.015, 0.016, 0.016, 0.016, 0.017, 0.016, 0.016, 0.016, 0.016, 0.015, 0.016, 0.017, 0.016, 0.016, 0.017, 0.016, 0.016, 0.016
Preview of result: [[1695727848, 0.287562638736685], [2126430375, 0.00767794129708177], [5310550656, 0.380769772645687], [2519183283, 0.153176220930558], [6610062385, 0.662996225870666], [987168256, 0.924410189999928], [6615003609, 0.917112691225947], [4465232046, 0.684311931851536], [8654414565, 0.631485392105992], [
...
=========================
Performance tests for RemesPath (simple string mutations)
=========================
-Compiling query "@[:].z = s_sub(@, g, B)" took 0.088 ms the first time, including approximately 0.093 ms to tokenize the query. Subsequent executions are effectively free due to caching.
-To run pre-compiled query "@[:].z = s_sub(@, g, B)" on JNode from JSON of size 89556 into took 0.028 +/- 0.012 ms over 40 trials
-Query times (ms): 0.05, 0.044, 0.044, 0.034, 0.026, 0.027, 0.03, 0.042, 0.031, 0.032, 0.037, 0.036, 0.033, 0.04, 0.034, 0.036, 0.04, 0.031, 0.013, 0.028, 0.016, 0.059, 0.053, 0.021, 0.015, 0.017, 0.013, 0.014, 0.012, 0.027, 0.016, 0.017, 0.026, 0.016, 0.013, 0.014, 0.011, 0.03, 0.029, 0.016
+Compiling query "@[:].z = s_sub(@, g, B)" took 0.058 ms the first time, including approximately 0.054 ms to tokenize the query. Subsequent executions are effectively free due to caching.
+To run pre-compiled query "@[:].z = s_sub(@, g, B)" on JNode from JSON of size 89556 into took 0.02 +/- 0.009 ms over 40 trials
+Query times (ms): 0.022, 0.014, 0.011, 0.01, 0.011, 0.016, 0.01, 0.01, 0.018, 0.015, 0.013, 0.012, 0.028, 0.03, 0.014, 0.013, 0.016, 0.032, 0.013, 0.011, 0.01, 0.011, 0.042, 0.028, 0.021, 0.015, 0.017, 0.029, 0.021, 0.019, 0.016, 0.036, 0.026, 0.027, 0.026, 0.039, 0.026, 0.029, 0.025, 0.027
Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c"
...
=========================
Performance tests for RemesPath (simple number mutations)
=========================
-Compiling query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" took 0.078 ms the first time, including approximately 0.124 ms to tokenize the query. Subsequent executions are effectively free due to caching.
-To run pre-compiled query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" on JNode from JSON of size 89556 into took 0.039 +/- 0.008 ms over 40 trials
-Query times (ms): 0.042, 0.064, 0.034, 0.035, 0.036, 0.039, 0.034, 0.041, 0.045, 0.035, 0.039, 0.039, 0.032, 0.051, 0.048, 0.051, 0.034, 0.036, 0.033, 0.041, 0.036, 0.032, 0.039, 0.035, 0.034, 0.03, 0.057, 0.065, 0.038, 0.036, 0.024, 0.041, 0.036, 0.034, 0.039, 0.04, 0.035, 0.038, 0.038, 0.041
+Compiling query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" took 0.07 ms the first time, including approximately 0.075 ms to tokenize the query. Subsequent executions are effectively free due to caching.
+To run pre-compiled query "@[:].x = ifelse(@ < 0.5, @ + 3, @ - 3)" on JNode from JSON of size 89556 into took 0.023 +/- 0.007 ms over 40 trials
+Query times (ms): 0.046, 0.019, 0.018, 0.02, 0.018, 0.023, 0.024, 0.029, 0.02, 0.018, 0.016, 0.021, 0.017, 0.018, 0.029, 0.02, 0.018, 0.017, 0.037, 0.028, 0.034, 0.025, 0.019, 0.018, 0.019, 0.019, 0.019, 0.018, 0.018, 0.021, 0.018, 0.043, 0.032, 0.034, 0.027, 0.02, 0.018, 0.018, 0.019, 0.029
Preview of result: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c"
...
=========================
@@ -311,12 +311,12 @@ Performance tests for RemesPath (mutations with a for loop)
Compiling query "var xhalf = @[:].x < 0.5;
for lx = zip(@[:].l, xhalf);
lx[0] = ifelse(lx[1], foo, bar);
-end for;" took 0.237 ms the first time, including approximately 0.199 ms to tokenize the query. Subsequent executions are effectively free due to caching.
+end for;" took 0.121 ms the first time, including approximately 0.114 ms to tokenize the query. Subsequent executions are effectively free due to caching.
To run pre-compiled query "var xhalf = @[:].x < 0.5;
for lx = zip(@[:].l, xhalf);
lx[0] = ifelse(lx[1], foo, bar);
-end for;" on JNode from JSON of size 89556 into took 0.076 +/- 0.019 ms over 40 trials
-Query times (ms): 0.107, 0.083, 0.086, 0.073, 0.093, 0.076, 0.076, 0.08, 0.078, 0.072, 0.091, 0.101, 0.107, 0.09, 0.111, 0.097, 0.084, 0.091, 0.065, 0.109, 0.094, 0.08, 0.064, 0.067, 0.061, 0.063, 0.067, 0.073, 0.076, 0.073, 0.075, 0.071, 0.073, 0.073, 0.056, 0.041, 0.039, 0.041, 0.048, 0.039
+end for;" on JNode from JSON of size 89556 into took 0.042 +/- 0.013 ms over 40 trials
+Query times (ms): 0.101, 0.04, 0.038, 0.052, 0.051, 0.067, 0.085, 0.041, 0.042, 0.038, 0.046, 0.036, 0.036, 0.047, 0.048, 0.037, 0.037, 0.036, 0.041, 0.035, 0.034, 0.036, 0.044, 0.036, 0.035, 0.035, 0.036, 0.039, 0.034, 0.033, 0.035, 0.038, 0.034, 0.043, 0.033, 0.044, 0.035, 0.036, 0.036, 0.05
Preview of result: [["bar", false], ["bar", false], ["foo", true], ["foo", true], ["foo", true], ["foo", true], ["foo", true], ["bar", false], ["bar", false], ["bar", false], ["foo", true], ["foo", true], ["bar", false], ["bar", false], ["foo", true], ["bar", false], ["bar", false], ["bar", false], ["foo", true], ["ba
...
=========================
@@ -325,18 +325,18 @@ Testing performance of JSON compression and pretty-printing
Preview of json: [{"A": "Ky'c^g#~)0", "a": 1850111954, "b": 9318359041, "B": "Oyi:/ xxe2", "C": "sKCSa_^7Gg", "c": 7974777124, "d": 2670309238, "D": "0d_K)HmX!.", "E": ".uM*Z{0EJ_", "e": 6958410336, "f": 8050244728, "F": "1%SG_A!xB\t", "g": 3799657125, "G": "il1^k\\\nat*", "H": {"a": 6079042826, "b": 7292804611, "c"
...
-To compress JNode from JSON string of 89556 took 4.158 +/- 0.978 ms over 64 trials (minimal whitespace, sortKeys=TRUE)
-To compress JNode from JSON string of 89556 took 2.006 +/- 0.268 ms over 64 trials (minimal whitespace, sortKeys=FALSE)
-To Google-style pretty-print JNode from JSON string of 89556 took 4.772 +/- 1.072 ms over 64 trials (sortKeys=true, indent=4)
-To Whitesmith-style pretty-print JNode from JSON string of 89556 took 4.743 +/- 0.944 ms over 64 trials (sortKeys=true, indent=4)
-To PPrint-style pretty-print JNode from JSON string of 89556 took 6.002 +/- 0.285 ms over 64 trials (sortKeys=true, indent=4)
+To compress JNode from JSON string of 89556 took 3.792 +/- 0.297 ms over 64 trials (minimal whitespace, sortKeys=TRUE)
+To compress JNode from JSON string of 89556 took 2.113 +/- 0.4 ms over 64 trials (minimal whitespace, sortKeys=FALSE)
+To Google-style pretty-print JNode from JSON string of 89556 took 4.931 +/- 0.761 ms over 64 trials (sortKeys=true, indent=4)
+To Whitesmith-style pretty-print JNode from JSON string of 89556 took 4.862 +/- 0.613 ms over 64 trials (sortKeys=true, indent=4)
+To PPrint-style pretty-print JNode from JSON string of 89556 took 7.011 +/- 0.999 ms over 64 trials (sortKeys=true, indent=4)
=========================
Testing performance of JsonSchemaValidator and random JSON creation
=========================
-To create a random set of tweet JSON of size 167038 (15 tweets) based on the matching schema took 7.05 +/- 3.737 ms over 64 trials
-To compile the tweet schema to a validation function took 0.375 +/- 0.633 ms over 64 trials
-To validate tweet JSON of size 167038 (15 tweets) based on the compiled schema took 1.16 +/- 0.564 ms over 64 trials
+To create a random set of tweet JSON of size 171921 (15 tweets) based on the matching schema took 6.427 +/- 2.904 ms over 64 trials
+To compile the tweet schema to a validation function took 0.263 +/- 0.416 ms over 64 trials
+To validate tweet JSON of size 171921 (15 tweets) based on the compiled schema took 1.019 +/- 0.216 ms over 64 trials
=========================
Testing JSON grepper's API request tool
=========================