diff --git a/.vscode/settings.json b/.vscode/settings.json
index 9f45485ac..ca8eedb02 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -15,6 +15,7 @@
"bendrep",
"bendswitch",
"bendwhile",
+ "bubbleanimation",
"defint",
"Deref",
"Doesnt",
@@ -40,6 +41,7 @@
"idlwv",
"imagefromuri",
"INCREMENTERS",
+ "lineanimation",
"minilog",
"mlog",
"nbands",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce5fc14da..8aa28732a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,28 @@ Here are some of the features that notebooks bring:
- After each cell is executed we issue a `retall` command to make sure that we are at the top-level and not stopped in a weird state
+## 3.2.1 August 2023
+
+Notebook key behavior change: If you are running one or more cells, and there is an error from IDL for any cell being executed, all pending cells are cleared and not executed. This makes sure that, if later cells depend on earlier ones, that you don't have cascading failures.
+
+Resolve a problem with the language server where you can get into an infinite loop trying to resolve include statements in IDL when they end up including one another
+
+Add a potential fix for always-increasing loops when doing change detection for parsed files
+
+Fix an issue where, if you have the same folder or sub folder on IDL's path and in an open workspace, then you would get duplicate problems being reported. We now get the unique files from all folders on startup at once to resolve this.
+
+Fixed a bug where notebook cells would sometimes process in the wrong worker thread, causing inconsistencies with things like semantic tokens.
+
+Fixed a bug where semantic tokens (highlighting static class references) was wrong when tokens were built out of order from top down and left to right
+
+Added a new problem code that detects when the IDL include statement creates a circular include pattern
+
+Fixed a bug with semantic tokens in notebooks where the text would be highlighted as a semantic token in cells that don't have any semantic tokens
+
+When you click into the outputs from an IDL notebook that is being rendered by the IDL Extension, a blue outline appears over what you have selected to match VSCode's behavior
+
+Added logic when retrieving outputs from IDL to be more backwards compatible. As it was, you needed at least IDL 8.8.3, but it now supports pre-8.8.3 at your own risk.
+
## 3.2.0 August 2023
When the language server does not use a full parse, extract structure definitions. Before, this was a logic gap (and made the code faster), but they should be correctly resolved now with minimal performance hits.
diff --git a/apps/client-e2e/src/tests/interactions/notebooks-interact-right.ts b/apps/client-e2e/src/tests/interactions/notebooks-interact-right.ts
index 6645d6eec..7a070c6db 100644
--- a/apps/client-e2e/src/tests/interactions/notebooks-interact-right.ts
+++ b/apps/client-e2e/src/tests/interactions/notebooks-interact-right.ts
@@ -83,13 +83,13 @@ export const NotebooksInteractRight: RunnerFunction = async (init) => {
},
};
- // verify semantic tokens
+ // verify semantic tokens (have none in NB, so get none)
expect(
await init.client.client.sendRequest(
'textDocument/semanticTokens/full',
tokenParams
)
- ).toBeTruthy();
+ ).toBeNull();
// short pause
await Sleep(250);
diff --git a/apps/client-e2e/src/tests/interactions/pro-code-interacts-right.ts b/apps/client-e2e/src/tests/interactions/pro-code-interacts-right.ts
index 74825816e..c98e3c309 100644
--- a/apps/client-e2e/src/tests/interactions/pro-code-interacts-right.ts
+++ b/apps/client-e2e/src/tests/interactions/pro-code-interacts-right.ts
@@ -76,13 +76,13 @@ export const ProCodeInteractRight: RunnerFunction = async (init) => {
},
};
- // verify semantic tokens
+ // verify semantic tokens (have none in code, so get none)
expect(
await init.client.client.sendRequest(
'textDocument/semanticTokens/full',
tokenParams
)
- ).toBeTruthy();
+ ).toBeNull();
// short pause
await Sleep(250);
diff --git a/apps/client-e2e/src/tests/notebooks/_notebook-runner.ts b/apps/client-e2e/src/tests/notebooks/_notebook-runner.ts
index 7564be4a8..d79ba3856 100644
--- a/apps/client-e2e/src/tests/notebooks/_notebook-runner.ts
+++ b/apps/client-e2e/src/tests/notebooks/_notebook-runner.ts
@@ -4,8 +4,10 @@ import { Runner } from '../runner.class';
import { NotebookFormats_1_0_0 } from './notebook-formats-1.0.0';
import { NotebookFormats_2_0_0 } from './notebook-formats-2.0.0';
import { NotebookProblemsTrackRight } from './notebook-problems-track-right';
-import { RunNotebookRestart } from './notebook-restart';
+import { RunNotebookReset } from './notebook-reset';
import { RunNotebookStop } from './notebook-stop';
+import { RunENVIMessageListenerTestNotebook } from './run-envi-message-listener-test-notebook';
+import { RunProblemNotebooks } from './run-problem-notebooks';
import { RunTestENVIMapNotebook } from './run-test-envi-map-notebook';
import { RunTestENVINotebook } from './run-test-envi-notebook';
import { RunTestNotebook } from './run-test-notebook';
@@ -39,11 +41,17 @@ NOTEBOOK_RUNNER.addTest({
});
NOTEBOOK_RUNNER.addTest({
- name: 'Run notebook that tests everything',
+ name: 'Run notebook that tests successes',
fn: RunTestNotebook,
critical: true,
});
+NOTEBOOK_RUNNER.addTest({
+ name: 'Run notebooks that test problems are handled right',
+ fn: RunProblemNotebooks,
+ critical: true,
+});
+
NOTEBOOK_RUNNER.addTest({
name: 'Save output and reload',
fn: SaveAndClearNotebook,
@@ -61,10 +69,16 @@ NOTEBOOK_RUNNER.addTest({
fn: RunTestENVIMapNotebook,
});
+// can get ENVI progress messages
+NOTEBOOK_RUNNER.addTest({
+ name: 'Notebooks can display progress messages from ENVI',
+ fn: RunENVIMessageListenerTestNotebook,
+});
+
// reset goes first
NOTEBOOK_RUNNER.addTest({
name: 'Reset does the right thing',
- fn: RunNotebookRestart,
+ fn: RunNotebookReset,
critical: true,
});
diff --git a/apps/client-e2e/src/tests/notebooks/helpers/compare-cells.interface.ts b/apps/client-e2e/src/tests/notebooks/helpers/compare-cells.interface.ts
index f36214046..5d8661ebc 100644
--- a/apps/client-e2e/src/tests/notebooks/helpers/compare-cells.interface.ts
+++ b/apps/client-e2e/src/tests/notebooks/helpers/compare-cells.interface.ts
@@ -13,7 +13,7 @@ export interface ICompareCellOutputs {
/** Cell we are comparing against */
idx: number;
/** did we succeed */
- success: boolean;
+ success: boolean | undefined;
/** All of the cell mimetypes */
mimeTypes: MimeTypes[];
}
diff --git a/apps/client-e2e/src/tests/notebooks/helpers/compare-cells.ts b/apps/client-e2e/src/tests/notebooks/helpers/compare-cells.ts
index 3da3d5387..6a47cf6fd 100644
--- a/apps/client-e2e/src/tests/notebooks/helpers/compare-cells.ts
+++ b/apps/client-e2e/src/tests/notebooks/helpers/compare-cells.ts
@@ -37,8 +37,10 @@ export function CompareCellOutputs(
expect(nbCell).not.toBeUndefined();
// validate success if we have it
- if (nbCell.executionSummary.success !== undefined) {
- expect(nbCell.executionSummary.success).toEqual(expected.success);
+ if (expected.success) {
+ expect(nbCell.executionSummary?.success).toBeTruthy();
+ } else {
+ expect(nbCell.executionSummary?.success).toBeFalsy();
}
// get output mime types
diff --git a/apps/client-e2e/src/tests/notebooks/helpers/run-notebook-and-compare-cells.ts b/apps/client-e2e/src/tests/notebooks/helpers/run-notebook-and-compare-cells.ts
new file mode 100644
index 000000000..75b107d77
--- /dev/null
+++ b/apps/client-e2e/src/tests/notebooks/helpers/run-notebook-and-compare-cells.ts
@@ -0,0 +1,68 @@
+import { NOTEBOOK_FOLDER } from '@idl/notebooks/shared';
+import { Sleep } from '@idl/shared';
+import { IDLNotebookController } from '@idl/vscode/notebooks';
+import { OpenNotebookInVSCode, VSCODE_COMMANDS } from '@idl/vscode/shared';
+import expect from 'expect';
+import { existsSync, rmSync } from 'fs';
+import * as vscode from 'vscode';
+
+import { CompareCellOutputs } from './compare-cells';
+import { ICompareCellOutputs } from './compare-cells.interface';
+
+/**
+ * helper function to:
+ *
+ * 1. Open notebook
+ * 2. Clear existing outputs
+ * 3. Run notebook
+ * 4. Compare expected outputs to actual outputs
+ * 5. Clear outputs
+ * 6. Close
+ */
+export async function RunNotebookAndCompareCells(
+ file: string,
+ cells: ICompareCellOutputs[],
+ controller: IDLNotebookController,
+ clear = true
+) {
+ // nuke .idl folder if it exists
+ if (existsSync(NOTEBOOK_FOLDER)) {
+ rmSync(NOTEBOOK_FOLDER, { recursive: true, force: true });
+ }
+
+ /**
+ * Open the notebook
+ */
+ const nb = await OpenNotebookInVSCode(file);
+
+ // clear any existing outputs
+ await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
+
+ // save to disk
+ await nb.save();
+
+ // run all cells
+ await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_RUN_ALL);
+
+ // make sure launched
+ expect(controller.isStarted()).toBeTruthy();
+
+ // short pause
+ await Sleep(100);
+
+ // compare cells
+ CompareCellOutputs(nb, cells);
+
+ if (clear) {
+ // clear outputs
+ await vscode.commands.executeCommand(
+ VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS
+ );
+ }
+
+ // save again
+ await nb.save();
+
+ // clear any existing outputs
+ await vscode.commands.executeCommand(VSCODE_COMMANDS.CLOSE_EDITOR);
+}
diff --git a/apps/client-e2e/src/tests/notebooks/notebook-restart.ts b/apps/client-e2e/src/tests/notebooks/notebook-reset.ts
similarity index 96%
rename from apps/client-e2e/src/tests/notebooks/notebook-restart.ts
rename to apps/client-e2e/src/tests/notebooks/notebook-reset.ts
index 60f7748ea..c5d0a94ad 100644
--- a/apps/client-e2e/src/tests/notebooks/notebook-restart.ts
+++ b/apps/client-e2e/src/tests/notebooks/notebook-reset.ts
@@ -22,7 +22,7 @@ export const CELL_OUTPUT: ICompareCellOutputs[] = [
* Function that verifies that we can do basic debugging of IDL sessions
* and launch a new debugging session.
*/
-export const RunNotebookRestart: RunnerFunction = async (init) => {
+export const RunNotebookReset: RunnerFunction = async (init) => {
/**
* Get the file we are going to open
*/
@@ -56,12 +56,12 @@ export const RunNotebookRestart: RunnerFunction = async (init) => {
// make sure stopped
expect(init.notebooks.controller.isStarted()).toBeTruthy();
- // clear outputs
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
-
// compare state
CompareCellOutputs(nb, CELL_OUTPUT);
+ // clear outputs
+ await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
+
// clear any existing outputs
await vscode.commands.executeCommand(VSCODE_COMMANDS.CLOSE_EDITOR);
};
diff --git a/apps/client-e2e/src/tests/notebooks/notebook-stop.ts b/apps/client-e2e/src/tests/notebooks/notebook-stop.ts
index a454d0102..acfdb80ce 100644
--- a/apps/client-e2e/src/tests/notebooks/notebook-stop.ts
+++ b/apps/client-e2e/src/tests/notebooks/notebook-stop.ts
@@ -56,9 +56,6 @@ export const RunNotebookStop: RunnerFunction = async (init) => {
// make sure stopped
expect(init.notebooks.controller.isStarted()).toBeFalsy();
- // clear outputs
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
-
// compare state
CompareCellOutputs(nb, CELL_OUTPUT);
diff --git a/apps/client-e2e/src/tests/notebooks/run-envi-message-listener-test-notebook.ts b/apps/client-e2e/src/tests/notebooks/run-envi-message-listener-test-notebook.ts
new file mode 100644
index 000000000..63b7174d4
--- /dev/null
+++ b/apps/client-e2e/src/tests/notebooks/run-envi-message-listener-test-notebook.ts
@@ -0,0 +1,61 @@
+import { GetExtensionPath } from '@idl/shared';
+
+import { RunnerFunction } from '../runner.interface';
+import { ICompareCellOutputs } from './helpers/compare-cells.interface';
+import { RunNotebookAndCompareCells } from './helpers/run-notebook-and-compare-cells';
+
+/**
+ * Types of outputs from cells that we expect to have
+ */
+export const CELL_OUTPUT: ICompareCellOutputs[] = [
+ {
+ idx: 0,
+ success: true,
+ mimeTypes: [],
+ },
+ {
+ idx: 1,
+ success: true,
+ mimeTypes: [],
+ },
+ {
+ idx: 2,
+ success: true,
+ mimeTypes: ['text/plain'],
+ },
+ {
+ idx: 3,
+ success: true,
+ mimeTypes: [],
+ },
+ {
+ idx: 4,
+ success: true,
+ mimeTypes: [],
+ },
+ {
+ idx: 5,
+ success: true,
+ mimeTypes: [],
+ },
+ {
+ idx: 6,
+ success: true,
+ mimeTypes: ['text/plain'],
+ },
+];
+
+/**
+ * Function that runs basic tests for ENVI message listeners
+ */
+export const RunENVIMessageListenerTestNotebook: RunnerFunction = async (
+ init
+) => {
+ await RunNotebookAndCompareCells(
+ GetExtensionPath(
+ 'idl/test/client-e2e/notebooks/envi-message-listener.idlnb'
+ ),
+ CELL_OUTPUT,
+ init.notebooks.controller
+ );
+};
diff --git a/apps/client-e2e/src/tests/notebooks/run-problem-notebooks.ts b/apps/client-e2e/src/tests/notebooks/run-problem-notebooks.ts
new file mode 100644
index 000000000..0e76ed048
--- /dev/null
+++ b/apps/client-e2e/src/tests/notebooks/run-problem-notebooks.ts
@@ -0,0 +1,101 @@
+import { GetExtensionPath } from '@idl/shared';
+
+import { RunnerFunction } from '../runner.interface';
+import { RunNotebookAndCompareCells } from './helpers/run-notebook-and-compare-cells';
+
+/**
+ * Function that verifies that we can do basic debugging of IDL sessions
+ * and launch a new debugging session.
+ */
+export const RunProblemNotebooks: RunnerFunction = async (init) => {
+ /**
+ * Verify we do the right thing on a stop
+ */
+ await RunNotebookAndCompareCells(
+ GetExtensionPath('idl/test/client-e2e/notebooks/problems/on-stop.idlnb'),
+ [
+ {
+ idx: 0,
+ success: true,
+ mimeTypes: [],
+ },
+ {
+ idx: 1,
+ success: false,
+ mimeTypes: ['text/plain'],
+ },
+ {
+ idx: 2,
+ success: undefined,
+ mimeTypes: [],
+ },
+ {
+ idx: 3,
+ success: undefined,
+ mimeTypes: [],
+ },
+ ],
+ init.notebooks.controller
+ );
+
+ /**
+ * Re-run our stop notebook to make sure we have properly returned from
+ * our stop
+ */
+ await RunNotebookAndCompareCells(
+ GetExtensionPath('idl/test/client-e2e/notebooks/problems/on-stop.idlnb'),
+ [
+ {
+ idx: 0,
+ success: true,
+ mimeTypes: [],
+ },
+ ],
+ init.notebooks.controller
+ );
+
+ /**
+ * First syntax error notebook
+ */
+ await RunNotebookAndCompareCells(
+ GetExtensionPath(
+ 'idl/test/client-e2e/notebooks/problems/syntax-err1.idlnb'
+ ),
+ [
+ {
+ idx: 0,
+ success: false,
+ mimeTypes: ['text/plain'],
+ },
+ {
+ idx: 1,
+ success: undefined,
+ mimeTypes: [],
+ },
+ ],
+ init.notebooks.controller
+ );
+
+ /**
+ * Second syntax error notebook
+ */
+
+ await RunNotebookAndCompareCells(
+ GetExtensionPath(
+ 'idl/test/client-e2e/notebooks/problems/syntax-err2.idlnb'
+ ),
+ [
+ {
+ idx: 0,
+ success: false,
+ mimeTypes: ['text/plain'],
+ },
+ {
+ idx: 1,
+ success: undefined,
+ mimeTypes: [],
+ },
+ ],
+ init.notebooks.controller
+ );
+};
diff --git a/apps/client-e2e/src/tests/notebooks/run-test-envi-map-notebook.ts b/apps/client-e2e/src/tests/notebooks/run-test-envi-map-notebook.ts
index b3380e38d..47afe7827 100644
--- a/apps/client-e2e/src/tests/notebooks/run-test-envi-map-notebook.ts
+++ b/apps/client-e2e/src/tests/notebooks/run-test-envi-map-notebook.ts
@@ -1,14 +1,9 @@
-import { NOTEBOOK_FOLDER } from '@idl/notebooks/shared';
import { IDL_NOTEBOOK_MIME_TYPE } from '@idl/notebooks/types';
-import { GetExtensionPath, Sleep } from '@idl/shared';
-import { OpenNotebookInVSCode, VSCODE_COMMANDS } from '@idl/vscode/shared';
-import expect from 'expect';
-import { existsSync, rmSync } from 'fs';
-import * as vscode from 'vscode';
+import { GetExtensionPath } from '@idl/shared';
import { RunnerFunction } from '../runner.interface';
-import { CompareCellOutputs } from './helpers/compare-cells';
import { ICompareCellOutputs } from './helpers/compare-cells.interface';
+import { RunNotebookAndCompareCells } from './helpers/run-notebook-and-compare-cells';
/**
* Types of outputs from cells that we expect to have
@@ -65,44 +60,11 @@ export const CELL_OUTPUT: ICompareCellOutputs[] = [
* Function that runs a notebook with test maps
*/
export const RunTestENVIMapNotebook: RunnerFunction = async (init) => {
- /**
- * Get the file we are going to open
- */
- const file = GetExtensionPath(
- 'idl/test/client-e2e/notebooks/test-notebook-envi-maps.idlnb'
+ await RunNotebookAndCompareCells(
+ GetExtensionPath(
+ 'idl/test/client-e2e/notebooks/test-notebook-envi-maps.idlnb'
+ ),
+ CELL_OUTPUT,
+ init.notebooks.controller
);
-
- // nuke .idl folder if it exists
- if (existsSync(NOTEBOOK_FOLDER)) {
- rmSync(NOTEBOOK_FOLDER, { recursive: true, force: true });
- }
-
- /**
- * Open the notebook
- */
- const nb = await OpenNotebookInVSCode(file);
-
- // clear any existing outputs
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
-
- // save to disk
- await nb.save();
-
- // run all cells
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_RUN_ALL);
-
- // make sure launched
- expect(init.notebooks.controller.isStarted()).toBeTruthy();
-
- // short pause
- await Sleep(100);
-
- // compare cells
- CompareCellOutputs(nb, CELL_OUTPUT);
-
- // clear any existing outputs
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
-
- // save to disk
- await nb.save();
};
diff --git a/apps/client-e2e/src/tests/notebooks/run-test-envi-notebook.ts b/apps/client-e2e/src/tests/notebooks/run-test-envi-notebook.ts
index e9014ab84..dc7834bc8 100644
--- a/apps/client-e2e/src/tests/notebooks/run-test-envi-notebook.ts
+++ b/apps/client-e2e/src/tests/notebooks/run-test-envi-notebook.ts
@@ -1,14 +1,9 @@
-import { NOTEBOOK_FOLDER } from '@idl/notebooks/shared';
import { IDL_NOTEBOOK_MIME_TYPE } from '@idl/notebooks/types';
-import { GetExtensionPath, Sleep } from '@idl/shared';
-import { OpenNotebookInVSCode, VSCODE_COMMANDS } from '@idl/vscode/shared';
-import expect from 'expect';
-import { existsSync, rmSync } from 'fs';
-import * as vscode from 'vscode';
+import { GetExtensionPath } from '@idl/shared';
import { RunnerFunction } from '../runner.interface';
-import { CompareCellOutputs } from './helpers/compare-cells';
import { ICompareCellOutputs } from './helpers/compare-cells.interface';
+import { RunNotebookAndCompareCells } from './helpers/run-notebook-and-compare-cells';
/**
* Types of outputs from cells that we expect to have
@@ -85,44 +80,9 @@ export const CELL_OUTPUT: ICompareCellOutputs[] = [
* Function that runs a test ENVI notebooks
*/
export const RunTestENVINotebook: RunnerFunction = async (init) => {
- /**
- * Get the file we are going to open
- */
- const file = GetExtensionPath(
- 'idl/test/client-e2e/notebooks/envi-test-notebook.idlnb'
+ await RunNotebookAndCompareCells(
+ GetExtensionPath('idl/test/client-e2e/notebooks/envi-test-notebook.idlnb'),
+ CELL_OUTPUT,
+ init.notebooks.controller
);
-
- // nuke .idl folder if it exists
- if (existsSync(NOTEBOOK_FOLDER)) {
- rmSync(NOTEBOOK_FOLDER, { recursive: true, force: true });
- }
-
- /**
- * Open the notebook
- */
- const nb = await OpenNotebookInVSCode(file);
-
- // clear any existing outputs
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
-
- // save to disk
- await nb.save();
-
- // run all cells
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_RUN_ALL);
-
- // make sure launched
- expect(init.notebooks.controller.isStarted()).toBeTruthy();
-
- // short pause
- await Sleep(100);
-
- // compare cells
- CompareCellOutputs(nb, CELL_OUTPUT);
-
- // clear any existing outputs
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
-
- // save to disk
- await nb.save();
};
diff --git a/apps/client-e2e/src/tests/notebooks/run-test-notebook.ts b/apps/client-e2e/src/tests/notebooks/run-test-notebook.ts
index 37d9b8f19..ed501f09f 100644
--- a/apps/client-e2e/src/tests/notebooks/run-test-notebook.ts
+++ b/apps/client-e2e/src/tests/notebooks/run-test-notebook.ts
@@ -1,14 +1,9 @@
-import { NOTEBOOK_FOLDER } from '@idl/notebooks/shared';
import { IDL_NOTEBOOK_MIME_TYPE } from '@idl/notebooks/types';
-import { GetExtensionPath, Sleep } from '@idl/shared';
-import { OpenNotebookInVSCode, VSCODE_COMMANDS } from '@idl/vscode/shared';
-import expect from 'expect';
-import { existsSync, rmSync } from 'fs';
-import * as vscode from 'vscode';
+import { GetExtensionPath } from '@idl/shared';
import { RunnerFunction } from '../runner.interface';
-import { CompareCellOutputs } from './helpers/compare-cells';
import { ICompareCellOutputs } from './helpers/compare-cells.interface';
+import { RunNotebookAndCompareCells } from './helpers/run-notebook-and-compare-cells';
/**
* Types of outputs from cells that we expect to have
@@ -83,31 +78,6 @@ export const CELL_OUTPUT: ICompareCellOutputs[] = [
IDL_NOTEBOOK_MIME_TYPE,
],
},
- {
- idx: 14,
- success: true,
- mimeTypes: [],
- },
- {
- idx: 15,
- success: false,
- mimeTypes: ['text/plain'],
- },
- {
- idx: 16,
- success: true,
- mimeTypes: ['text/plain'],
- },
- {
- idx: 17,
- success: false,
- mimeTypes: ['text/plain'],
- },
- {
- idx: 18,
- success: false,
- mimeTypes: ['text/plain'],
- },
];
/**
@@ -118,35 +88,11 @@ export const RunTestNotebook: RunnerFunction = async (init) => {
/**
* Get the file we are going to open
*/
- const file = GetExtensionPath(
- 'idl/test/client-e2e/notebooks/test-notebook.idlnb'
- );
-
- // nuke .idl folder if it exists
- if (existsSync(NOTEBOOK_FOLDER)) {
- rmSync(NOTEBOOK_FOLDER, { recursive: true, force: true });
- }
-
- /**
- * Open the notebook
- */
- const nb = await OpenNotebookInVSCode(file);
-
- // clear any existing outputs
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_CLEAR_OUTPUTS);
-
- // save to disk
- await nb.save();
-
- // run all cells
- await vscode.commands.executeCommand(VSCODE_COMMANDS.NOTEBOOK_RUN_ALL);
- // make sure launched
- expect(init.notebooks.controller.isStarted()).toBeTruthy();
-
- // short pause
- await Sleep(100);
-
- // compare cells
- CompareCellOutputs(nb, CELL_OUTPUT);
+ await RunNotebookAndCompareCells(
+ GetExtensionPath('idl/test/client-e2e/notebooks/test-notebook.idlnb'),
+ CELL_OUTPUT,
+ init.notebooks.controller,
+ false
+ );
};
diff --git a/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.html b/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.html
new file mode 100644
index 000000000..b4e20cc42
--- /dev/null
+++ b/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.html
@@ -0,0 +1,49 @@
+
diff --git a/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.spec.ts b/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.spec.ts
new file mode 100644
index 000000000..44718fa98
--- /dev/null
+++ b/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AnimationControlsComponent } from './animation-controls.component';
+
+describe('AnimationControlsComponent', () => {
+ let component: AnimationControlsComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [AnimationControlsComponent],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(AnimationControlsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.ts b/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.ts
new file mode 100644
index 000000000..190ed79e6
--- /dev/null
+++ b/apps/notebook/components/src/app/components/animation-controls/animation-controls.component.ts
@@ -0,0 +1,164 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+
+/**
+ * Round a number to the nearest increment
+ */
+export function RoundToNearest(num: number, to: number) {
+ return num === 0 ? 0 : Math.round(Math.max(num / to, 1)) * to;
+}
+
+@Component({
+ selector: 'idl-nb-animation-controls',
+ templateUrl: './animation-controls.component.html',
+ styles: [
+ `
+ @import 'shared-styles.scss';
+ `,
+ ],
+})
+export class AnimationControlsComponent implements OnInit {
+ /**
+ * The maximum number of frames that we have
+ */
+ @Input() nFrames = 1;
+
+ /**
+ * Animation interval (ms)
+ */
+ @Input() interval = 1000;
+
+ /**
+ * Output event that is emitted when our frame changes
+ */
+ @Output() frameChange = new EventEmitter();
+
+ /**
+ * The current frame we are on
+ */
+ frame = 0;
+
+ /**
+ * Multiplier for speed
+ */
+ multiplier = 1;
+
+ /**
+ * When we click fast forward or slow down, what do we do?
+ */
+ fastMultiplier = 2;
+
+ /**
+ * If we are paused or not
+ */
+ isPaused = false;
+
+ /**
+ * reference to current animation timeout
+ */
+ private _timeout!: any | undefined;
+
+ ngOnInit() {
+ this.play();
+ }
+
+ /**
+ * Get text for our video speed
+ */
+ multiplierText() {
+ return `${RoundToNearest(
+ 1 / this.multiplier,
+ this.multiplier > 1 ? 0.1 : 1
+ )}x`;
+ }
+
+ /**
+ * If slider changes because user make it change
+ */
+ onInputChange(ev: Event) {
+ // update our tracked frame
+ this.frame = +(ev.target as HTMLInputElement).value;
+
+ // emit event
+ this.frameChange.next(this.frame);
+ }
+
+ /**
+ * Label for the tooltip
+ */
+ label(value: number) {
+ return `${value + 1}`;
+ }
+
+ /**
+ * Sets a timeout to animate through our images
+ */
+ play() {
+ // update flag
+ this.isPaused = false;
+
+ this._timeout = setTimeout(() => {
+ // clear timeout reference
+ this._timeout = undefined;
+
+ // increment frame number
+ this.frame++;
+
+ // if we reached our limit, start at zero
+ if (this.frame >= this.nFrames) {
+ this.frame = 0;
+ }
+
+ // emit event
+ this.frameChange.next(this.frame);
+
+ // animate again
+ this.play();
+ }, this.getInterval());
+ }
+
+ /**
+ * Gets the interval time (in ms) given current parameters
+ */
+ getInterval() {
+ return this.interval * this.multiplier;
+ }
+
+ /**
+ * Pauses execution
+ */
+ pauseOrPlay() {
+ if (!this.isPaused) {
+ this.pause();
+ } else {
+ this.play();
+ }
+ }
+
+ /**
+ * Resets/stops timeout for next frame
+ */
+ pause() {
+ this.isPaused = true;
+ if (this._timeout !== undefined) {
+ window.clearTimeout(this._timeout);
+ }
+ }
+
+ /**
+ * Makes it play faster
+ */
+ speedUp() {
+ this.pause();
+ this.multiplier = Math.max((this.multiplier /= this.fastMultiplier), 0.125);
+ this.play();
+ }
+
+ /**
+ * Makes it play slower
+ */
+ slowDown() {
+ this.pause();
+ this.multiplier = Math.min((this.multiplier *= this.fastMultiplier), 2);
+ this.play();
+ }
+}
diff --git a/apps/notebook/components/src/app/components/components.module.ts b/apps/notebook/components/src/app/components/components.module.ts
index 03968af30..352e826c2 100644
--- a/apps/notebook/components/src/app/components/components.module.ts
+++ b/apps/notebook/components/src/app/components/components.module.ts
@@ -4,21 +4,23 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { MaterialCssVarsModule } from 'angular-material-css-vars';
import { MaterialModule } from '../material.module';
+import { AnimationControlsComponent } from './animation-controls/animation-controls.component';
import { EntryComponent } from './entry/entry.component';
import { ImageComponent } from './image/image.component';
import { ImageAnimatorComponent } from './image-animator/image-animator.component';
import { MapComponent } from './map/map.component';
import { MapPropertySheetComponent } from './map/map-property-sheet/map-property-sheet.component';
-import { Plot2DComponent } from './plot2d/plot2d.component';
+import { PlotComponent } from './plot/plot.component';
@NgModule({
declarations: [
EntryComponent,
ImageComponent,
ImageAnimatorComponent,
- Plot2DComponent,
+ PlotComponent,
MapComponent,
MapPropertySheetComponent,
+ AnimationControlsComponent,
],
imports: [
CommonModule,
@@ -30,9 +32,10 @@ import { Plot2DComponent } from './plot2d/plot2d.component';
EntryComponent,
ImageComponent,
ImageAnimatorComponent,
- Plot2DComponent,
+ PlotComponent,
MapComponent,
MapPropertySheetComponent,
+ AnimationControlsComponent,
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [],
diff --git a/apps/notebook/components/src/app/components/entry/entry.component.html b/apps/notebook/components/src/app/components/entry/entry.component.html
index 067494eb2..b82cd1fe3 100644
--- a/apps/notebook/components/src/app/components/entry/entry.component.html
+++ b/apps/notebook/components/src/app/components/entry/entry.component.html
@@ -1,28 +1,30 @@
-
+
+
-
-
+
+
-
+
-
+
-
+
-
-
Unhandled embed type of "{{ embed.type }}"
-
-
+
+
Unhandled embed type of "{{ embed.type }}"
+
+
-
- No data to render!
-
+
+ No data to render!
+
+
diff --git a/apps/notebook/components/src/app/components/entry/entry.component.ts b/apps/notebook/components/src/app/components/entry/entry.component.ts
index a08c332d2..1d8257e1b 100644
--- a/apps/notebook/components/src/app/components/entry/entry.component.ts
+++ b/apps/notebook/components/src/app/components/entry/entry.component.ts
@@ -1,4 +1,10 @@
-import { Component, Host, Input } from '@angular/core';
+import {
+ AfterViewInit,
+ Component,
+ ElementRef,
+ Host,
+ Input,
+} from '@angular/core';
import {
IDLNotebook_EmbedType,
IDLNotebookEmbeddedItem,
@@ -27,12 +33,13 @@ export const IDL_NB_ENTRY_COMPONENT_SELECTOR = 'idl-nb-entry';
templateUrl: './entry.component.html',
styles: [
`
+ @import 'shared-styles.scss';
@import 'styles.scss';
`,
],
providers: [DataSharingService],
})
-export class EntryComponent {
+export class EntryComponent implements AfterViewInit {
/**
* Flag if we have data or not
*/
@@ -61,5 +68,19 @@ export class EntryComponent {
*/
embed!: IDLNotebookEmbeddedItem;
- constructor(@Host() private dataShare: DataSharingService) {}
+ class = '';
+
+ constructor(
+ @Host() private dataShare: DataSharingService,
+ private el: ElementRef
+ ) {}
+
+ ngAfterViewInit() {
+ this.el.nativeElement.onclick = () => {
+ this.class = 'vscode-outlined';
+ };
+ this.el.nativeElement.onmouseleave = () => {
+ this.class = '';
+ };
+ }
}
diff --git a/apps/notebook/components/src/app/components/image-animator/image-animator.component.html b/apps/notebook/components/src/app/components/image-animator/image-animator.component.html
index 8c6defdc3..fa7485d05 100644
--- a/apps/notebook/components/src/app/components/image-animator/image-animator.component.html
+++ b/apps/notebook/components/src/app/components/image-animator/image-animator.component.html
@@ -3,61 +3,13 @@
-
+ [nFrames]="this._embed.item.data.length"
+ (frameChange)="setSource($event)"
+ >
diff --git a/apps/notebook/components/src/app/components/image-animator/image-animator.component.ts b/apps/notebook/components/src/app/components/image-animator/image-animator.component.ts
index fb740f244..cea53d3ca 100644
--- a/apps/notebook/components/src/app/components/image-animator/image-animator.component.ts
+++ b/apps/notebook/components/src/app/components/image-animator/image-animator.component.ts
@@ -33,154 +33,21 @@ export class ImageAnimatorComponent
*/
src = 'not set';
- /**
- * The current frame we are on
- */
- frame = 0;
-
- /**
- * Default interval in seconds
- */
- interval = 1000;
-
- /**
- * Multiplier for speed
- */
- multiplier = 1;
-
- /**
- * When we click fast forward or slow down, what do we do?
- */
- fastMultiplier = 2;
-
- /**
- * If we are paused or not
- */
- isPaused = false;
-
- /**
- * reference to current animation timeout
- */
- private _timeout!: any | undefined;
-
/**
* On init, set up our animation
*/
ngOnInit(): void {
if (this.hasData) {
- this.setSource();
- this.play();
- }
- }
-
- multiplierText() {
- return `${RoundToNearest(
- 1 / this.multiplier,
- this.multiplier > 1 ? 0.1 : 1
- )}x`;
- }
-
- /**
- * If slider changes because user make it change
- */
- onInputChange(ev: Event) {
- this.frame = +(ev.target as HTMLInputElement).value;
- this.setSource();
- }
-
- /**
- * Label for the tooltip
- */
- label(value: number) {
- return `${value + 1}`;
- }
-
- /**
- * Sets a timeout to animate through our images
- */
- play() {
- // update flag
- this.isPaused = false;
-
- if (!this.hasData) {
- return;
- }
-
- // set image source
- this.setSource();
-
- this._timeout = setTimeout(() => {
- // clear timeout reference
- this._timeout = undefined;
-
- // increment frame number
- this.frame++;
-
- // if we reached our limit, start at zero
- if (this.frame >= this._embed.item.data.length) {
- this.frame = 0;
- }
-
- // set image source
- this.setSource();
-
- // animate again
- this.play();
- }, this.getInterval());
- }
-
- /**
- * Gets the interval time (in ms) given current parameters
- */
- getInterval() {
- return this.interval * this.multiplier;
- }
-
- /**
- * Pauses execution
- */
- pauseOrPlay() {
- if (!this.isPaused) {
- this.pause();
- } else {
- this.play();
- }
- }
-
- /**
- * Resets/stops timeout for next frame
- */
- pause() {
- this.isPaused = true;
- if (this._timeout !== undefined) {
- window.clearTimeout(this._timeout);
+ this.setSource(0);
}
}
/**
* Sets image source to the latest image data
*/
- setSource() {
+ setSource(frame: number) {
if (this.hasData) {
- this.src = `data:image/png;base64,${this._embed.item.data[this.frame]}`;
+ this.src = `data:image/png;base64,${this._embed.item.data[frame]}`;
}
}
-
- /**
- * Makes it play faster
- */
- speedUp() {
- this.pause();
- this.multiplier = Math.max((this.multiplier /= this.fastMultiplier), 0.125);
- this.play();
- }
-
- /**
- * Makes it play slower
- */
- slowDown() {
- this.pause();
- this.multiplier = Math.min((this.multiplier *= this.fastMultiplier), 2);
- this.play();
- }
}
diff --git a/apps/notebook/components/src/app/components/map/helpers/create-layers.ts b/apps/notebook/components/src/app/components/map/helpers/create-layers.ts
index f6912fde6..a1ea13520 100644
--- a/apps/notebook/components/src/app/components/map/helpers/create-layers.ts
+++ b/apps/notebook/components/src/app/components/map/helpers/create-layers.ts
@@ -7,6 +7,7 @@ import {
IDLNotebookMap_Image,
} from '@idl/notebooks/types';
import { bboxify } from '@mapbox/geojson-extent';
+import { nanoid } from 'nanoid';
import { AwesomeImage } from './awesome-image.class';
@@ -70,12 +71,13 @@ export function CreateLayers(embed: IDLNotebookEmbeddedItem
) {
embedLayers.push(
new GeoJsonLayer({
+ id: nanoid(),
stroked: true,
filled: true,
getFillColor: (geo) => {
if (geo.properties && 'color' in geo.properties) {
const rgb = geo.properties['color'];
- return [rgb[0], rgb[1], rgb[2], 125];
+ return [rgb[0], rgb[1], rgb[2], 175];
} else {
return color as any;
}
@@ -111,7 +113,7 @@ export function CreateLayers(embed: IDLNotebookEmbeddedItem) {
embedLayers.push(
new AwesomeImage({
- id: 'bitmap-layer',
+ id: nanoid(),
image: `data:image/png;base64,${typed.item.data}`,
bounds: [extent.xmin, extent.ymin, extent.xmax, extent.ymax],
pickable: false,
diff --git a/apps/notebook/components/src/app/components/plot/helpers/chart-config.ts b/apps/notebook/components/src/app/components/plot/helpers/chart-config.ts
new file mode 100644
index 000000000..36e54bc7c
--- /dev/null
+++ b/apps/notebook/components/src/app/components/plot/helpers/chart-config.ts
@@ -0,0 +1,66 @@
+import {
+ IDLNotebookEmbeddedItem,
+ IDLNotebookPlot,
+ IDLNotebookPlot_Properties,
+} from '@idl/notebooks/types';
+import copy from 'fast-copy';
+
+/**
+ * Default chart configuration for plots
+ */
+const DEFAULT_CONFIG: IDLNotebookPlot_Properties = {
+ plugins: {
+ legend: {
+ display: false,
+ },
+ },
+};
+
+/**
+ * If we have an animation, custom overrides for default plot options
+ */
+const DEFAULT_ANIMATION_OPTIONS: IDLNotebookPlot_Properties = {
+ animation: false,
+ frameInterval: 1000,
+};
+
+/**
+ * Configuration options that cannot be overridden by users
+ */
+const ALWAYS_THIS_CONFIG: IDLNotebookPlot_Properties = {
+ responsive: true,
+ maintainAspectRatio: true,
+};
+
+/**
+ * Creates the configuration for our chart
+ */
+export function ChartConfig(
+ embed: IDLNotebookEmbeddedItem,
+ animation: boolean
+) {
+ /**
+ * Copy our starting point for options
+ */
+ const options = copy(DEFAULT_CONFIG);
+
+ /**
+ * If we are an animation, tweak some options
+ */
+ if (animation) {
+ Object.assign(options, DEFAULT_ANIMATION_OPTIONS);
+ }
+
+ /**
+ * Check if we have options from our plot
+ */
+ if (embed.item.properties) {
+ Object.assign(options, embed.item.properties);
+ }
+
+ // verify our constant options are set
+ Object.assign(options, ALWAYS_THIS_CONFIG);
+
+ // return options
+ return options;
+}
diff --git a/apps/notebook/components/src/app/components/plot/helpers/create-plots.interface.ts b/apps/notebook/components/src/app/components/plot/helpers/create-plots.interface.ts
new file mode 100644
index 000000000..2881f1f10
--- /dev/null
+++ b/apps/notebook/components/src/app/components/plot/helpers/create-plots.interface.ts
@@ -0,0 +1,24 @@
+import { ChartDataset } from 'chart.js';
+
+/**
+ * Callback data structure for an animation frame
+ */
+export type PlotAnimationCallback = (frame: number) => void;
+
+/**
+ * Data structure for plots that we created
+ */
+export type CreatedPlots = {
+ /**
+ * Chart datasets
+ */
+ data: ChartDataset[];
+ /**
+ * Animation callbacks
+ */
+ animationCallbacks: PlotAnimationCallback[];
+ /**
+ * Largest number of frames
+ */
+ nFrames: number;
+};
diff --git a/apps/notebook/components/src/app/components/plot/helpers/create-plots.ts b/apps/notebook/components/src/app/components/plot/helpers/create-plots.ts
new file mode 100644
index 000000000..60353ac10
--- /dev/null
+++ b/apps/notebook/components/src/app/components/plot/helpers/create-plots.ts
@@ -0,0 +1,212 @@
+import {
+ IDLNotebookEmbeddedItem,
+ IDLNotebookPlot,
+ IDLNotebookPlot_Bubble,
+ IDLNotebookPlot_BubbleAnimation,
+ IDLNotebookPlot_Line,
+ IDLNotebookPlot_LineAnimation,
+} from '@idl/notebooks/types';
+import { ChartDataset } from 'chart.js';
+
+import { CreatedPlots, PlotAnimationCallback } from './create-plots.interface';
+
+/**
+ * Creates plot data for display in an IDL Notebook
+ */
+export function CreatePlots(
+ embed: IDLNotebookEmbeddedItem
+): CreatedPlots {
+ /**
+ * The plot data
+ */
+ const data: ChartDataset[] = [];
+
+ /**
+ * Animation frame callbacks
+ */
+ const animationCallbacks: PlotAnimationCallback[] = [];
+
+ /**
+ * Get all items to embed
+ */
+ const toEmbed = embed.item.data;
+
+ /**
+ * Maximum number of frames
+ */
+ let nFrames = 0;
+
+ // process all datasets
+ for (let i = 0; i < toEmbed.length; i++) {
+ switch (toEmbed[i].type) {
+ /**
+ * Check for line/scatter plot
+ */
+ case 'idlnotebookplot_line': {
+ /** Strictly type */
+ const typed = toEmbed[
+ i
+ ] as IDLNotebookEmbeddedItem;
+
+ // create typed dataset
+ const plotData: ChartDataset<'scatter'> = {
+ type: 'scatter',
+ label: `Plot ${i + 1}`,
+ data: typed.item.y.map((y, idx) => {
+ return { x: typed.item.x[idx], y };
+ }),
+ showLine: true,
+ // pointRadius: 0,
+ pointStyle: 'triangle',
+ pointBorderColor: 'red',
+ pointBackgroundColor: 'red',
+ };
+
+ // create chart
+ data.push(plotData);
+ break;
+ }
+
+ /**
+ * Check for line/scatter animation
+ */
+ case 'idlnotebookplot_lineanimation': {
+ /** Strictly type */
+ const typed = toEmbed[
+ i
+ ] as IDLNotebookEmbeddedItem;
+
+ // skip if no data
+ if (typed.item.frames.length === 0) {
+ continue;
+ }
+
+ // get the first frame
+ const first = typed.item.frames[0];
+
+ // create typed dataset
+ const plotData: ChartDataset<'scatter'> = {
+ type: 'scatter',
+ label: `Plot ${i + 1}`,
+ data: first.y.map((y, idx) => {
+ return { x: first.x[idx], y };
+ }),
+ showLine: true,
+ // pointRadius: 0,
+ pointStyle: 'triangle',
+ pointBorderColor: 'red',
+ pointBackgroundColor: 'red',
+ };
+
+ // update the number of frames
+ nFrames = Math.max(nFrames, typed.item.frames.length);
+
+ /**
+ * Add callback for our animation
+ */
+ animationCallbacks.push((frame: number) => {
+ const fIdx = Math.min(frame, typed.item.frames.length - 1);
+
+ /**
+ * Get the frame we show
+ */
+ const showFrame = typed.item.frames[fIdx];
+
+ // update label
+ plotData.label = `Plot ${i + 1}, Frame ${fIdx + 1}`;
+
+ /** update plot data */
+ plotData.data = showFrame.y.map((y, idx) => {
+ return { x: showFrame.x[idx], y };
+ });
+ });
+
+ // create chart
+ data.push(plotData);
+ break;
+ }
+
+ /**
+ * Check for bubble plot
+ */
+ case 'idlnotebookplot_bubble': {
+ /** Strictly type */
+ const typed = toEmbed[
+ i
+ ] as IDLNotebookEmbeddedItem;
+
+ // create typed dataset
+ const plotData: ChartDataset<'bubble'> = {
+ type: 'bubble',
+ label: `Plot ${i + 1}`,
+ data: typed.item.y.map((y, idx) => {
+ return { x: typed.item.x[idx], y, r: typed.item.r[idx] };
+ }),
+ };
+
+ // create chart
+ data.push(plotData);
+ break;
+ }
+
+ /**
+ * Check for bubble plot animation
+ */
+ case 'idlnotebookplot_bubbleanimation': {
+ /** Strictly type */
+ const typed = toEmbed[
+ i
+ ] as IDLNotebookEmbeddedItem;
+
+ // skip if no data
+ if (typed.item.frames.length === 0) {
+ continue;
+ }
+
+ // get the first frame
+ const first = typed.item.frames[0];
+
+ // create typed dataset
+ const plotData: ChartDataset<'bubble'> = {
+ type: 'bubble',
+ label: `Bubble plot ${i + 1}`,
+ data: first.y.map((y, idx) => {
+ return { x: first.x[idx], y, r: first.r[idx] };
+ }),
+ };
+
+ // update the number of frames
+ nFrames = Math.max(nFrames, typed.item.frames.length);
+
+ /**
+ * Add callback for our animation
+ */
+ animationCallbacks.push((frame: number) => {
+ const fIdx = Math.min(frame, typed.item.frames.length - 1);
+
+ /**
+ * Get the frame we show
+ */
+ const showFrame = typed.item.frames[fIdx];
+
+ // update label
+ plotData.label = `Bubble plot ${i + 1}, Frame ${fIdx + 1}`;
+
+ /** update plot data */
+ plotData.data = showFrame.y.map((y, idx) => {
+ return { x: showFrame.x[idx], y, r: showFrame.r[idx] };
+ });
+ });
+
+ // track chart data
+ data.push(plotData);
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ return { data, animationCallbacks, nFrames };
+}
diff --git a/apps/notebook/components/src/app/components/plot/plot.component.html b/apps/notebook/components/src/app/components/plot/plot.component.html
new file mode 100644
index 000000000..de5c83602
--- /dev/null
+++ b/apps/notebook/components/src/app/components/plot/plot.component.html
@@ -0,0 +1,18 @@
+
+
+
0"
+ [ngStyle]="{
+ width: (PlotCanvas.offsetWidth || 500) + 'px'
+ }"
+ [nFrames]="plots.nFrames"
+ [interval]="interval"
+ (frameChange)="setFrame($event)"
+ >
+
+
+
+
+
+
No data to plot!
+
diff --git a/apps/notebook/components/src/app/components/plot2d/plot2d.component.spec.ts b/apps/notebook/components/src/app/components/plot/plot.component.spec.ts
similarity index 54%
rename from apps/notebook/components/src/app/components/plot2d/plot2d.component.spec.ts
rename to apps/notebook/components/src/app/components/plot/plot.component.spec.ts
index bb847c184..ebad00ff0 100644
--- a/apps/notebook/components/src/app/components/plot2d/plot2d.component.spec.ts
+++ b/apps/notebook/components/src/app/components/plot/plot.component.spec.ts
@@ -1,17 +1,17 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { Plot2DComponent } from './plot2d.component';
+import { PlotComponent } from './plot.component';
-describe('Plot2DComponent', () => {
- let component: Plot2DComponent;
- let fixture: ComponentFixture;
+describe('PlotComponent', () => {
+ let component: PlotComponent;
+ let fixture: ComponentFixture;
beforeEach(async () => {
await TestBed.configureTestingModule({
- declarations: [Plot2DComponent],
+ declarations: [PlotComponent],
}).compileComponents();
- fixture = TestBed.createComponent(Plot2DComponent);
+ fixture = TestBed.createComponent(PlotComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
diff --git a/apps/notebook/components/src/app/components/plot2d/plot2d.component.ts b/apps/notebook/components/src/app/components/plot/plot.component.ts
similarity index 52%
rename from apps/notebook/components/src/app/components/plot2d/plot2d.component.ts
rename to apps/notebook/components/src/app/components/plot/plot.component.ts
index 9cb2ac505..a749faec2 100644
--- a/apps/notebook/components/src/app/components/plot2d/plot2d.component.ts
+++ b/apps/notebook/components/src/app/components/plot/plot.component.ts
@@ -6,41 +6,41 @@ import {
SkipSelf,
ViewChild,
} from '@angular/core';
-import { IDLNotebookPlot2D } from '@idl/notebooks/types';
+import { IDLNotebookPlot } from '@idl/notebooks/types';
import Chart from 'chart.js/auto';
import { VSCodeRendererMessenger } from '../../services/vscode-renderer-messenger.service';
import { BaseRendererComponent } from '../base-renderer.component';
import { DataSharingService } from '../data-sharing.service';
+import { ChartConfig } from './helpers/chart-config';
+import { CreatePlots } from './helpers/create-plots';
+import { CreatedPlots } from './helpers/create-plots.interface';
/**
* ID for notebook image selector
*/
-export const IDL_NB_PLOT2D_COMPONENT_SELECTOR = 'idl-nb-plot2d';
+export const IDL_NB_PLOT_COMPONENT_SELECTOR = 'idl-nb-plot';
/**
* Component that creates a 2D line plot from data
*/
@Component({
- selector: 'idl-nb-plot2d',
- templateUrl: './plot2d.component.html',
+ selector: 'idl-nb-plot',
+ templateUrl: './plot.component.html',
styles: [
`
- .chart-container {
- max-width: 90%;
- aspect-ratio: 1;
- }
+ @import 'shared-styles.scss';
`,
],
})
-export class Plot2DComponent
- extends BaseRendererComponent
+export class PlotComponent
+ extends BaseRendererComponent
implements AfterViewInit, OnDestroy
{
/**
* Canvas we draw to
*/
- @ViewChild('Plot2DCanvas')
+ @ViewChild('PlotCanvas')
canvas!: ElementRef;
/**
@@ -48,6 +48,20 @@ export class Plot2DComponent
*/
private chart: Chart | undefined;
+ /**
+ * Track a reference to our created plots
+ */
+ plots: CreatedPlots = {
+ data: [],
+ animationCallbacks: [],
+ nFrames: 0,
+ };
+
+ /**
+ * Frame rate for animations
+ */
+ interval = 1000;
+
/**
* Callback to resize chart on window resize
*
@@ -80,36 +94,58 @@ export class Plot2DComponent
window.addEventListener('resize', this.resizeCb);
}
+ /**
+ * If we have an animation, updates chart data
+ */
+ setFrame(frame: number) {
+ if (this.hasData) {
+ const nAnimations = this.plots.animationCallbacks.length;
+ if (nAnimations > 0) {
+ for (let i = 0; i < nAnimations; i++) {
+ this.plots.animationCallbacks[i](frame);
+ }
+
+ // update chart with no animation
+ this.chart?.update('none');
+ }
+ }
+ }
+
/**
* Remove callbacks to prevent memory leaks
*/
ngOnDestroy() {
window.removeEventListener('resize', this.resizeCb);
+ if (this.hasData) {
+ this.hasData = false;
+ this.plots = {
+ animationCallbacks: [],
+ data: [],
+ nFrames: 0,
+ };
+ this.chart?.destroy();
+ }
}
ngAfterViewInit() {
if (this.hasData) {
+ // create plot data
+ this.plots = CreatePlots(this._embed);
+
+ // create options for our plot
+ const options = ChartConfig(this._embed, this.plots.nFrames > 0);
+
+ // update interval
+ if (options.frameInterval !== undefined) {
+ this.interval = options.frameInterval;
+ }
+
+ // create our charts
this.chart = new Chart(this.canvas.nativeElement, {
- type: 'scatter',
data: {
- datasets: [
- {
- label: 'Test',
- data: this._embed.item.y.map((y, idx) => {
- return { x: this._embed.item.x[idx], y };
- }),
- showLine: true,
- // pointRadius: 0,
- pointStyle: 'triangle',
- pointBorderColor: 'red',
- pointBackgroundColor: 'red',
- },
- ],
- },
- options: {
- responsive: true,
- maintainAspectRatio: true,
+ datasets: this.plots.data,
},
+ options,
});
}
}
diff --git a/apps/notebook/components/src/app/components/plot2d/plot2d.component.html b/apps/notebook/components/src/app/components/plot2d/plot2d.component.html
deleted file mode 100644
index b97cd1bd5..000000000
--- a/apps/notebook/components/src/app/components/plot2d/plot2d.component.html
+++ /dev/null
@@ -1,2 +0,0 @@
-
-No data to plot!
diff --git a/apps/notebook/components/src/app/services/vscode-renderer-messenger.service.ts b/apps/notebook/components/src/app/services/vscode-renderer-messenger.service.ts
index 0c9db469c..897eed753 100644
--- a/apps/notebook/components/src/app/services/vscode-renderer-messenger.service.ts
+++ b/apps/notebook/components/src/app/services/vscode-renderer-messenger.service.ts
@@ -1,46 +1,96 @@
-import { Injectable } from '@angular/core';
+import { Injectable, OnDestroy } from '@angular/core';
import {
- IDLNotebookRendererMessage,
- IDLNotebookRendererMessageType,
+ IDLNotebookFromRendererBaseMessage,
+ IDLNotebookFromRendererMessage,
+ IDLNotebookFromRendererMessageType,
+ IDLNotebookOutputMetadata,
+ IDLNotebookToRendererMessage,
} from '@idl/notebooks/types';
+import { nanoid } from 'nanoid';
+import { Subject } from 'rxjs';
import type { RendererContext } from 'vscode-notebook-renderer';
@Injectable({
providedIn: 'any',
})
-export class VSCodeRendererMessenger {
+export class VSCodeRendererMessenger implements OnDestroy {
/**
* Renderer context from VSCode so we can send messages
*/
private context!: RendererContext;
+ /**
+ * The output ID of the cell
+ */
+ private metadata!: IDLNotebookOutputMetadata;
+
+ /**
+ * Observable for messages from VSCode
+ *
+ * All messages are filtered by our cell ID
+ */
+ messages$ = new Subject();
+
/** If we have a light or dark theme */
darkTheme = true;
constructor() {
+ // get messaging context
if ('_vscodeContext' in window) {
this.context = (window as any)._vscodeContext;
}
+ // get the ID of our output item
+ if ('_vscodeCellOutputMetadata' in window) {
+ this.metadata = (window as any)._vscodeCellOutputMetadata;
+ }
+
// flag if dark mode
this.darkTheme = !document.body.classList.contains('vscode-light');
+
+ // listen for messages
+ if (
+ this.canPostMessage() &&
+ this.context.onDidReceiveMessage !== undefined
+ ) {
+ this.context.onDidReceiveMessage((msg: IDLNotebookToRendererMessage) => {
+ if (msg.cellId === this.metadata.id) {
+ this.messages$.next(msg);
+ }
+ });
+ }
+ }
+
+ /**
+ * Listen for destroy lifecycle to clean up
+ */
+ ngOnDestroy() {
+ // clean up observable
+ this.messages$.complete();
}
/**
* Method that tells us if we can post messages or not
*/
canPostMessage() {
- return this.context.postMessage !== undefined;
+ return (
+ this.context.postMessage !== undefined && this.metadata !== undefined
+ );
}
/**
* Posts message to notebook controller
*/
- postMessage(
- message: IDLNotebookRendererMessage
+ postMessage(
+ message: IDLNotebookFromRendererBaseMessage
) {
if (this?.context?.postMessage !== undefined) {
- this.context.postMessage(message);
+ const typed: IDLNotebookFromRendererMessage = {
+ messageId: nanoid(),
+ cellId: this.metadata.id,
+ ...message,
+ };
+ this.context.postMessage(typed);
}
}
}
diff --git a/apps/notebook/renderer/src/main.ts b/apps/notebook/renderer/src/main.ts
index 364a1dc6f..66e633900 100644
--- a/apps/notebook/renderer/src/main.ts
+++ b/apps/notebook/renderer/src/main.ts
@@ -18,6 +18,9 @@ export const activate: ActivationFunction = (context) => {
// save context
(window as any)._vscodeContext = context;
+ // save ID for cell output item
+ (window as any)._vscodeCellOutputMetadata = data.metadata;
+
// create key for data for better data transfer
const dataKey = `${Math.floor(Date.now() * 1000)}`;
diff --git a/apps/test-tokenizer/src/test-maker/cache/cache.json b/apps/test-tokenizer/src/test-maker/cache/cache.json
index e0115180b..9d92a7b92 100644
--- a/apps/test-tokenizer/src/test-maker/cache/cache.json
+++ b/apps/test-tokenizer/src/test-maker/cache/cache.json
@@ -1 +1 @@
-{"auto-token-tests":{"assignment.spec.ts":"{\"suiteName\":\"Validates assignment parsing\",\"fileName\":\"assignment.spec.ts\",\"tests\":[{\"name\":\"parses variable assignment\",\"code\":\"a = 5\"},{\"name\":\"parses system variable assignment\",\"code\":\"!null = 5\"},{\"name\":\"brackets with assignment\",\"code\":\"a[i] = b\"},{\"name\":\"parses variable assignment with line continuation\",\"code\":[\"z = $\",\" 5\"]},{\"name\":\"assignment with parentheses\",\"code\":\"(b) = 15\"},{\"name\":\"procedure after assignment in loop and keyword\",\"code\":\"for i=0, myFunc(a=42) do print, i\"}]}","blocks.spec.ts":"{\"suiteName\":\"Validates block parsing auto-closes\",\"fileName\":\"blocks.spec.ts\",\"tests\":[{\"name\":\"lib example from kruskal_wallis.pro\",\"code\":[\"\",\"if !true then $\",\"\",\"while !true DO BEGIN\",\" a = 42 \",\"ENDWHILE $\",\"\",\"ELSE stop = stop+1\",\"end\"]}]}","brackets.spec.ts":"{\"suiteName\":\"Validates bracket parsing\",\"fileName\":\"brackets.spec.ts\",\"tests\":[{\"name\":\"parses standalone brackets\",\"code\":\"[1 + 2]\"},{\"name\":\"parses standalone brackets with line continuations\",\"code\":[\"[1 + $\",\" 2]\"]},{\"name\":\"indexing and compound expression\",\"code\":\"array1[1 + 2] * (1 + 2)\"},{\"name\":\"brackets with assignment\",\"code\":\"_a[i] = 5 * b\"},{\"name\":\"brackets with compound assignment\",\"code\":\"_aA$[i] *= b\"}]}","colon.spec.ts":"{\"suiteName\":\"Validates colon parsing\",\"fileName\":\"colon.spec.ts\",\"tests\":[{\"name\":\"simple colon test\",\"code\":\"[:]\"},{\"name\":\"array indexing\",\"code\":\"a[0:I] = 42\"}]}","commas.spec.ts":"{\"suiteName\":\"Validates comma parsing (mostly covered elsewhere)\",\"fileName\":\"commas.spec.ts\",\"tests\":[{\"name\":\"don't find commas on their own\",\"code\":\",\"},{\"name\":\"find commas in function\",\"code\":\"f(,)\"},{\"name\":\"find commas in pro\",\"code\":\"p,\"}]}","comments.spec.ts":"{\"suiteName\":\"Validates comment parsing\",\"fileName\":\"comments.spec.ts\",\"tests\":[{\"name\":\"parses simple comments\",\"code\":\" ; something()\"},{\"name\":\"parses code with comments at the end\",\"code\":\"a = b() ; something()\"},{\"name\":\"parses simple comments with TODO\",\"code\":\" ; TODO: something()\"},{\"name\":\"parses code with comments at the end with TODO\",\"code\":\"a = b() ; TODO: something()\"},{\"name\":\"parses code with comments and line continuations\",\"code\":[\"a = $ ; TODO: something()\",\" b()\"]}]}","control.1.spec.ts":"{\"suiteName\":\"Validates control statement parsing\",\"fileName\":\"control.1.spec.ts\",\"tests\":[{\"name\":\"parses basic control statements\",\"code\":[\"break\",\"continue\",\"jump: a = func()\",\"jump: mypro, $\",\" 5\",\"jumpy17$: ;comment\"]},{\"name\":\"parses break in if statements\",\"code\":\"if !true then break\"},{\"name\":\"parses continue in if statements\",\"code\":\"if !true then continue\"},{\"name\":\"parses continue and break in loops\",\"code\":[\"for i=0,99 do begin\",\" continue\",\" break\",\"endfor\"]},{\"name\":\"parses jump in blocks\",\"code\":[\"for i=0,99 do begin\",\" jump:\",\"endfor\"]},{\"name\":\"parses compound control statements\",\"code\":[\"common, group, var1, var2, var3 ; comment\",\"compile_opt, idl2, $ ; line continuation\",\" hidden\",\"compile_opt\",\"forward_function, idl2, hidden\",\"goto, label\"]},{\"name\":\"goto in in statement\",\"code\":\"if not wild then goto, done else printf, outunit\"},{\"name\":\"statements end at line separator\",\"code\":\"GOTO, do_six & END\"}]}","executive-command.spec.ts":"{\"suiteName\":\"Validates executive command parsing\",\"fileName\":\"executive-command.spec.ts\",\"tests\":[{\"name\":\"simple 1\",\"code\":\".compile\"},{\"name\":\"simple 2\",\"code\":\".run myfile.pro\"},{\"name\":\"simple 3 start with spaces\",\"code\":\" .run myfile.pro\"},{\"name\":\"ignore methods\",\"code\":\"obj.method\"},{\"name\":\"ignore properties\",\"code\":\"!null = obj.method\"}]}","include.spec.ts":"{\"suiteName\":\"Validates include statements, but not correct location\",\"fileName\":\"include.spec.ts\",\"tests\":[{\"name\":\"basic test\",\"code\":\"@includeme\"},{\"name\":\"don't find in functions\",\"code\":\"a = myfunc(@bad)\"},{\"name\":\"find in loops\",\"code\":\"for i=0,99 do @very_wrong\"},{\"name\":\"don't find in expressions\",\"code\":\"a = @include_wrong + @way_bad\"},{\"name\":\"don't capture afterwards\",\"code\":\"@include.pro ; comment\"}]}","lambda.spec.ts":"{\"suiteName\":\"Validates lambda functions parsed as special token\",\"fileName\":\"lambda.spec.ts\",\"tests\":[{\"name\":\"correctly parse lambda functions\",\"code\":\"a = lambda(x:x+2)\"}]}","line-modifiers.spec.ts":"{\"suiteName\":\"Validates line modifier (separators)\",\"fileName\":\"line-modifiers.spec.ts\",\"tests\":[{\"name\":\"parses multi-line as single-line\",\"code\":[\"a = a + b() & proc & a.procMethod,1 & $\",\"a={struct}\"]},{\"name\":\"loops properly stop in line modifier\",\"code\":[\"proc & for i=0,99 do print, i & while !true do b = awesome() & foreach val, b, key do print, key, val & endedit\"]},{\"name\":\"line separators in case statement\",\"code\":[\"CASE typ OF\",\" 7: begin val = \\\"\\\" & cnt = 1 & endcase\",\" 8: val = tiff_sint(val, 0, len=cnt)\",\"ENDCASE\"]},{\"name\":\"verifies nested line continuations use basic token\",\"code\":\"scale=scale, $, $\"}]}","logic.if-then-else.1.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [1]\",\"fileName\":\"logic.if-then-else.1.spec.ts\",\"tests\":[{\"name\":\"parses basic if-then loop\",\"code\":\"if !true then print, 'yes'\"},{\"name\":\"parses basic if-then-else loop\",\"code\":\"if ~doIt then print, 'yes' else a = yellow()\"},{\"name\":\"parses basic if-then loop with line continuation 1\",\"code\":[\"if !true $\",\" then print, 'yes'\"]},{\"name\":\"parses basic if-then loop with line continuation 2\",\"code\":[\"if !true $\",\" then print $\",\" , 'yes'\"]},{\"name\":\"parses basic if-then-else loop with line continuation 1\",\"code\":[\"if !true then print, 'yes' $\",\" else print, 'no'\"]},{\"name\":\"parses basic if-then-else loop with line continuation 2\",\"code\":[\"if !true then print, 'yes' $\",\" else $\",\" print, 'no'\"]},{\"name\":\"nested if-then-else\",\"code\":\"if ~(myFunc(_a17$) * 2) then if !false then print, 'yes'\"}]}","logic.if-then-else.2.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [2]\",\"fileName\":\"logic.if-then-else.2.spec.ts\",\"tests\":[{\"name\":\"with blocks [1]\",\"code\":[\"if a++ then begin\",\" super = awesome()\",\"endif else print, 'else'\"]}]}","logic.if-then-else.3.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [3]\",\"fileName\":\"logic.if-then-else.3.spec.ts\",\"tests\":[{\"name\":\"example from IDL code [1]\",\"code\":\"if i ne 0 then a[0, m1-i] = y ;Symmetrical\"},{\"name\":\"example from IDL code [2]\",\"code\":[\"if (ISA(equation)) then begin\",\" graphic.SetProperty, EQUATION=equation\",\" arg1 = equation\",\" if (ISA(style)) then arg2 = style\",\"endif\"]},{\"name\":\"example from IDL code [3]\",\"code\":[\"IF (nms[i-1, j] && ~marked[i-1, j]) THEN $\",\" canny_follow, i-1, j, nms, marked\"]},{\"name\":\"example from IDL code [4]\",\"code\":[\"IF (max(step) && ~n_elements(stepflag)) THEN $\",\" suppMag = nmsupp_mask * mag\"]},{\"name\":\"example from IDL code [5]\",\"code\":[\"if (~Isa(hDefinition, 'Hash') || $\",\" ~hDefinition.HasKey('schema') || $\",\" ~(hDefinition['schema']).StartsWith('IDLColorGradientDefinition', /FOLD_CASE)) then begin\",\" message, 'File does not contain a valid color gradient definition.', /NONAME \",\"endif\"]}]}","logic.case.1.spec.ts":"{\"suiteName\":\"Validates case statement\",\"fileName\":\"logic.case.1.spec.ts\",\"tests\":[{\"name\":\"parses case loop with many syntaxes\",\"code\":[\"CASE x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\"ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDCASE\"]},{\"name\":\"nested case statement\",\"code\":[\"CASE x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" CASE x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDCASE\",\"END\",\"ENDCASE\"]}]}","logic.switch.1.spec.ts":"{\"suiteName\":\"Validates switch statement\",\"fileName\":\"logic.switch.1.spec.ts\",\"tests\":[{\"name\":\"parses switch loop with many syntaxes\",\"code\":[\"SWITCH x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\"ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDSWITCH\"]},{\"name\":\"nested switch statement\",\"code\":[\"SWITCH x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" SWITCH x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDSWITCH\",\"END\",\"ENDSWITCH\"]}]}","logic.ternary.1.spec.ts":"{\"suiteName\":\"Validates for ternary statement parsing\",\"fileName\":\"logic.ternary.1.spec.ts\",\"tests\":[{\"name\":\"simplest ternary statement\",\"code\":\"a = something ? 5 : 6\"},{\"name\":\"nested ternary statement grouped\",\"code\":\"a = !true ? (!false ? 7 : 8) : 6\"},{\"name\":\"nested ternary statement without grouping\",\"code\":\"mypro, something ? ~something ? 7 : 8 : 6, 2\"},{\"name\":\"ternary as argument\",\"code\":\"a = myfunc(something ? otherfunc() : !awesomesauce) + 3\"},{\"name\":\"operators end on ternary statements\",\"code\":\"a = 5*something ? 5- 4 : 6^3\"},{\"name\":\"multi-line ternary 1\",\"code\":[\"a = _myvar $\",\" ? 'jello' : \\\"jelly\\\"\"]},{\"name\":\"multi-line ternary 2\",\"code\":[\"a = myfunc( $\",\" a,b,c) ? b4d $\",\" : $\",\" s1nt4x3x4mple\"]},{\"name\":\"ternary works in braces as expected\",\"code\":[\"_17 = arr[!true ? 0 : -3: -1]\"]}]}","loops.for.spec.ts":"{\"suiteName\":\"Validates for loop parsing\",\"fileName\":\"loops.for.spec.ts\",\"tests\":[{\"name\":\"parses basic for loop\",\"code\":\"for i=0, 99 do print, i\"},{\"name\":\"parses basic for loop with increment\",\"code\":\"for i=0, 99, 2 do !null = myFunc(i)\"},{\"name\":\"parses basic for loop with line continuation\",\"code\":[\"for i=0, jj do $\",\" print, i\"]},{\"name\":\"parses basic for loop with block\",\"code\":[\"for i=0, 99 do begin\",\" !null = myFunc(i)\",\"endfor\"]},{\"name\":\"parses nested for loop\",\"code\":\"for i=0, 99 do for j=0, 99 do print, i + j\"}]}","loops.foreach.spec.ts":"{\"suiteName\":\"Validates foreach loop parsing\",\"fileName\":\"loops.foreach.spec.ts\",\"tests\":[{\"name\":\"parses basic foreach loop\",\"code\":\"foreach val, arr do print, i\"},{\"name\":\"parses basic foreach loop with key\",\"code\":\"foreach val, arr, idx do !null = myFunc(i)\"},{\"name\":\"parses basic foreach loop with line continuation\",\"code\":[\"foreach val, arr do $\",\" print, i\"]},{\"name\":\"parses basic foreach loop with block\",\"code\":[\"foreach val, arr do begin\",\" !null = myFunc(i)\",\"endforeach\"]},{\"name\":\"parses nested foreach loop\",\"code\":\"foreach val, arr do foreach val2, val do print, val2\"}]}","loops.repeat.spec.ts":"{\"suiteName\":\"Validates repeat loop parsing\",\"fileName\":\"loops.repeat.spec.ts\",\"tests\":[{\"name\":\"parses basic repeat loop\",\"code\":\"REPEAT A = A * 2 UNTIL A GT B\"},{\"name\":\"parses procedure in repeat loop\",\"code\":\"REPEAT PRINT, A UNTIL A GT B\"},{\"name\":\"parses basic repeat loop with line continuations\",\"code\":[\"REPEAT A = $\",\" A * 2 UNTIL $\",\" A GT B\"]},{\"name\":\"parses basic repeat loop with block\",\"code\":[\"REPEAT BEGIN\",\" A = A * 2\",\"ENDREP UNTIL A GT B\"]},{\"name\":\"correctly parses loops with if statements inside\",\"code\":[\"repeat if !true then break until !true\"]}]}","loops.while.spec.ts":"{\"suiteName\":\"Validates while loop parsing\",\"fileName\":\"loops.while.spec.ts\",\"tests\":[{\"name\":\"parses basic while loop\",\"code\":\"while !true do print, i\"},{\"name\":\"parses basic nested while loop\",\"code\":\"while !true do while !false do print, i\"},{\"name\":\"parses basic while loop with line continuation\",\"code\":[\"while !true do $\",\" print, $\",\" i\"]},{\"name\":\"parses basic while loop with block\",\"code\":[\"while (a eq 5) do begin\",\" !null = myFunc(i)\",\"endwhile\"]}]}","methods.functions.spec.ts":"{\"suiteName\":\"Validates function method parsing\",\"fileName\":\"methods.functions.spec.ts\",\"tests\":[{\"name\":\"parses function methods with dots\",\"code\":\"!NULL = a.myFunc(1)\"},{\"name\":\"parses function methods with arrows\",\"code\":\"!NULL = a->myFunc(1)\"},{\"name\":\"parses super function methods with dots\",\"code\":\"a.super::myfunc(1)\"},{\"name\":\"parses super function methods with arrows\",\"code\":\"a->super::myfunc(a)\"},{\"name\":\"parses function methods with dots and line continuation\",\"code\":[\"!NULL = a.myFunc( $\",\" 1)\"]},{\"name\":\"single-character function method\",\"code\":\"a.b()\"}]}","methods.procedures.spec.ts":"{\"suiteName\":\"Validates procedure method parsing\",\"fileName\":\"methods.procedures.spec.ts\",\"tests\":[{\"name\":\"parses procedure methods with dots\",\"code\":\"a.myProc, 1\"},{\"name\":\"parses procedure methods with arrows\",\"code\":\"a->myProc, a\"},{\"name\":\"parses super procedure methods with dots\",\"code\":\"a.super::myProc, 1\"},{\"name\":\"parses super procedure methods with arrows\",\"code\":\"a->super::myProc, a\"},{\"name\":\"parses procedure methods with dots and line continuations\",\"code\":[\"a.myProc, $\",\" 1\"]},{\"name\":\"procedure method from IDL lib\",\"code\":[\"((*state).markers).Add, CGRAD_NEW_MARKER(POSITION=marker['position'], $\",\" COLOR=color, $\",\" MIDDLE=marker['middle'])\"]},{\"name\":\"single-character procedure method\",\"code\":\"a.b\"}]}","numbers.spec.ts":"{\"suiteName\":\"Validates special cases for number parsing\",\"fileName\":\"numbers.spec.ts\",\"tests\":[{\"name\":\"correctly parse scientific notations\",\"code\":[\"a = -1e34\",\"a = -1e34i\",\"a = -1e34j\"]},{\"name\":\"correctly parse scientific notations with negatives 1\",\"code\":[\"a = 1e-34\",\"a = 1e-34i\",\"a = 1e-34j\"]},{\"name\":\"correctly parse scientific notations with negatives 2\",\"code\":[\"a = 1e-\",\"a = 1e-i\",\"a = 1e-j\"]},{\"name\":\"correctly parse hex notation\",\"code\":[\"a = 0x8FFF + 0x8Fub + 0x8FulL\",\"a = 0x8FFFI + 0x8FubI + 0x8FulLi\",\"a = 0x8FFFJ + 0x8Fubj + 0x8FulLJ\"]},{\"name\":\"correctly parse octal notation\",\"code\":[\"a = 0o8FFF + 0o8Fub + 0o8FulL\",\"a = 0o8FFFI + 0o8FubI + 0o8FulLi\",\"a = 0o8FFFJ + 0o8Fubj + 0o8FulLJ\"]},{\"name\":\"correctly parse binary notation\",\"code\":[\"a = 0b8FFF + 0b8Fub + 0b8FulL\",\"a = 0b8FFFI + 0b8FubI + 0b8FulLi\",\"a = 0b8FFFJ + 0b8Fubj + 0b8FulLJ\"]},{\"name\":\"correctly parse scientific notations with doubles\",\"code\":[\"a = -1d34\",\"a = -1d34i\",\"a = -1d34j\"]},{\"name\":\"correctly parse scientific notations with doubles with negatives 1\",\"code\":[\"a = 1d-34\",\"a = 1d-34i\",\"a = 1d-34j\"]},{\"name\":\"correctly parse scientific notations with doubles with negatives 2\",\"code\":[\"a = 1d-\",\"a = 1d-i\",\"a = 1d-j\"]},{\"name\":\"correctly parse new syntax for complex\",\"code\":[\"a = 1i\",\"a = 1j\"]},{\"name\":\"catch unfinished dot statement 1\",\"code\":\"a.\"},{\"name\":\"catch unfinished dot statement 2\",\"code\":\"a = b.\"},{\"name\":\"catch standalone dot\",\"code\":\"a = .\"},{\"name\":\"edge case scientific\",\"code\":\"a = .1e+12\"},{\"name\":\"solo dot\",\"code\":\".\"}]}","number-string.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36 + \\\"45\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36b + \\\"45ull\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'b\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'x\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'o\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"b\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"x\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"o\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XS\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XS\"}]}","number-string.complex-i.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.complex-i.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36i + \\\"45i\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36bi + \\\"45ulli\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'bi\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'xi\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'oi\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"bi\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"xi\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"oi\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XSi\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XSi\"}]}","number-string.complex-j.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.complex-j.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36j + \\\"45j\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36bj + \\\"45ullj\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'bj\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'xj\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'oj\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"bj\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"xj\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"oj\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XSj\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XSj\"}]}","operators.compound.spec.ts":"{\"suiteName\":\"Validates compound operator parsing\",\"fileName\":\"operators.compound.spec.ts\",\"tests\":[{\"name\":\"parses with line continuation\",\"code\":[\"z *= $\",\" 5\"]},{\"name\":\"does not recurse with \\\"||\\\" operator\",\"code\":\"a || b || c\"},{\"name\":\"does not recurse with \\\"or\\\" operator\",\"code\":\"a or b or c\"},{\"name\":\"captures all statements with \\\"&&\\\" operator\",\"code\":\"a && b && c\"},{\"name\":\"captures all statements with \\\"&&\\\" operator\",\"code\":\"a and b and c\"}]}","operators.spec.ts":"{\"suiteName\":\"Validates operator parsing\",\"fileName\":\"operators.spec.ts\",\"tests\":[{\"name\":\"close on braces\",\"code\":\"{1+2}\"},{\"name\":\"close on brackets\",\"code\":\"[1+2]\"},{\"name\":\"close on parentheses\",\"code\":\"(1+2)\"},{\"name\":\"close on commas\",\"code\":\"1+2,3+4\"},{\"name\":\"close on then and else\",\"code\":\"if 1+2 then a = 3+4 else a = 4^3\"},{\"name\":\"close on do in loops\",\"code\":\"for i=0, 99-1 do print, i\"},{\"name\":\"operators with line continuations\",\"code\":[\"zach + $ \",\"awesome\"]},{\"name\":\"operators end on \\\"of\\\"\",\"code\":[\"case n_params()-1 of\",\" 0: call_method, method_name, oObj[i], _extra=e\",\" 1: call_method, method_name, oObj[i], p1, _extra=e\",\"endcase\"]},{\"name\":\"operators end on arrow function\",\"code\":\"*(*pState).pTitle->SetProperty, color=[255, 255, 255]\"},{\"name\":\"operators end on procedure method\",\"code\":\"*pTitle.SetProperty, color=[255, 255, 255]\"},{\"name\":\"operators do not end on function method\",\"code\":\"*pTitle.SetProperty(color=[255, 255, 255])\"},{\"name\":\"operators do not end on function method\",\"code\":\"*pTitle->SetProperty(color=[255, 255, 255])\"},{\"name\":\"special token for increment\",\"code\":[\"++a\",\"a++\"]},{\"name\":\"special token for decrement\",\"code\":[\"--a\",\"a+--\"]},{\"name\":\"next to each other\",\"code\":\"a = b++ + 5\"}]}","parentheses.spec.ts":"{\"suiteName\":\"Validates parentheses parsing\",\"fileName\":\"parentheses.spec.ts\",\"tests\":[{\"name\":\"parses standalone parentheses\",\"code\":\"(1 + 2)\"},{\"name\":\"separate function from parentheses\",\"code\":\"myFunc(1 + 2) * (1 + 2)\"},{\"name\":\"parses standalone parentheses with line continuation\",\"code\":[\"(1 + $ \",\" 2)\"]}]}","prompts.spec.ts":"{\"suiteName\":\"Validates prompt parsing\",\"fileName\":\"prompts.spec.ts\",\"tests\":[{\"name\":\"parses IDL prompt\",\"code\":\"IDL> print, 42\"},{\"name\":\"parses ENVI prompt\",\"code\":\"ENVI> print, 17\"}]}","properties.spec.ts":"{\"suiteName\":\"Validates property parsing\",\"fileName\":\"properties.spec.ts\",\"tests\":[{\"name\":\"parses property assignment\",\"code\":\"a.thing = 5\"},{\"name\":\"parses property access\",\"code\":\"b = a.thing\"},{\"name\":\"parses property access with line continuation\",\"code\":[\"b = $\",\" a.thing\"]},{\"name\":\"parses nested property access\",\"code\":\"b = a.thing1.thing2\"},{\"name\":\"parses property access as arguments\",\"code\":\"myPro, a.thing, b.thing\"},{\"name\":\"property example from IDL lib\",\"code\":\"(*state).bottomSelection = lMarkers.Count()-1\"},{\"name\":\"structure property via indexing\",\"code\":\"a = b.(i)\"}]}","python.spec.ts":"{\"suiteName\":\"Validates Python code parsing\",\"fileName\":\"python.spec.ts\",\"tests\":[{\"name\":\"parses IDL prompt\",\"code\":\">>>import numpy as np\"}]}","quotes.spec.ts":"{\"suiteName\":\"Validates quote parsing\",\"fileName\":\"quotes.spec.ts\",\"tests\":[{\"name\":\"parses standalone single quotes\",\"code\":\"'myFunc(1 + 2)'\"},{\"name\":\"parses standalone double quotes\",\"code\":\"\\\"myFunc(1 + 2)\\\"\"},{\"name\":\"verify single quotes without closing\",\"code\":\"'string\"},{\"name\":\"verify double quotes without closing\",\"code\":\"\\\"string\"},{\"name\":\"confusing single quote\",\"code\":\"hDefinition['schema']).StartsWith('IDLColorGradientDefinition', /FOLD_CASE)\"},{\"name\":\"confusing double quote\",\"code\":\"hDefinition[\\\"schema\\\"]).StartsWith(\\\"IDLColorGradientDefinition\\\", /FOLD_CASE)\"},{\"name\":\"quotes end at important statements 1\",\"code\":[\"if \\\"bad-quote\\\"then \\\"bad-quote\\\"else\"]},{\"name\":\"quotes end at important statements 2\",\"code\":[\"case \\\"bad-quote\\\"of\"]},{\"name\":\"quotes end at important statements 3\",\"code\":[\"for \\\"bad-quote\\\"do\"]},{\"name\":\"quotes end at important statements 4\",\"code\":[\"repeat 'bad-quote'until\"]},{\"name\":\"quotes end at important statements 5\",\"code\":[\"if 'bad-quote'then 'bad-quote'else\"]},{\"name\":\"quotes end at important statements 6\",\"code\":[\"case 'bad-quote'of\"]},{\"name\":\"quotes end at important statements 7\",\"code\":[\"for 'bad-quote'do\"]},{\"name\":\"quotes end at important statements 8\",\"code\":[\"repeat 'bad-quote'until\"]},{\"name\":\"verifies quote vs number is correctly identified\",\"code\":[\"arr = [\\\"0.00000000\\\"]\"]}]}","quotes.escaped.spec.ts":"{\"suiteName\":\"Validates escaped quote parsing\",\"fileName\":\"quotes.escaped.spec.ts\",\"tests\":[{\"name\":\"simple single quote\",\"code\":\"'Resolve_Routine, ''%s'', Is_Function=%d'\"},{\"name\":\"simple double quote\",\"code\":\"\\\"Resolve_Routine, \\\"\\\"%s\\\"\\\", Is_Function=%d\\\"\"},{\"name\":\"complex single quote\",\"code\":\"'Resolve_Routine, ''%s'', Is_Function=%d''lots of''other''string'\"},{\"name\":\"complex double quote\",\"code\":\"\\\"Resolve_Routine, \\\"\\\"%s\\\"\\\", Is_Function=%d\\\"\\\"lots of\\\"\\\"other\\\"\\\"string\\\"\"}]}","quotes.edge-cases.spec.ts":"{\"suiteName\":\"Validates edge case quote parsing\",\"fileName\":\"quotes.edge-cases.spec.ts\",\"tests\":[{\"name\":\"for number-string like strings\",\"code\":\"a = \\\"5\\\"\"}]}","routines.functions.spec.ts":"{\"suiteName\":\"Validates function parsing\",\"fileName\":\"routines.functions.spec.ts\",\"tests\":[{\"name\":\"parses standalone functions\",\"code\":\"myFunc(1 + 2)\"},{\"name\":\"parses nested functions\",\"code\":\"myFunc(myFunc2(_y7$) + 2)\"},{\"name\":\"separate function from parentheses\",\"code\":\"myFunc(1 + 2) * (1 + 2)\"},{\"name\":\"parses standalone functions with line continuations\",\"code\":[\"myFunc(1 $\",\" + 2)\"]},{\"name\":\"single-character function\",\"code\":\"a()\"}]}","routines.keywords.spec.ts":"{\"suiteName\":\"Validates keyword parsing\",\"fileName\":\"routines.keywords.spec.ts\",\"tests\":[{\"name\":\"parses keyword assignment\",\"code\":\"myfunc(a = 5)\"},{\"name\":\"parses multiple keywords\",\"code\":\"_otherfunc(a = 5, _b=42)\"},{\"name\":\"parses multiple keywords with line continuation\",\"code\":[\"myfunc(a = 5, $\",\" _b=42)\"]},{\"name\":\"parses keyword assignment with line continuation\",\"code\":[\"myfunc(a $\",\" = 5)\"]},{\"name\":\"parses variable assignment\",\"code\":\"_y = _superFunction(a = 5)\"}]}","routines.procedures.spec.ts":"{\"suiteName\":\"Validates procedure parsing\",\"fileName\":\"routines.procedures.spec.ts\",\"tests\":[{\"name\":\"parses standalone procedures\",\"code\":\"myPro, 1 + 2\"},{\"name\":\"separate pro from variables\",\"code\":\"myPro, arg1, arg2\"},{\"name\":\"pro with line continuations\",\"code\":[\"myPro, $\",\" arg1, arg2\"]},{\"name\":\"pro in loop after arguments and function\",\"code\":\"for i=0, 2*5-jello(1) do print, i\"},{\"name\":\"single-character procedure\",\"code\":\"a\"}]}","routines.spacing.spec.ts":"{\"suiteName\":\"Validates routine spacing\",\"fileName\":\"routines.spacing.spec.ts\",\"tests\":[{\"name\":\"functions\",\"code\":\"myFunc (1 + 2)\"},{\"name\":\"procedures\",\"code\":\"mypro ,\"},{\"name\":\"function method (dots)\",\"code\":\"a . method ()\"},{\"name\":\"function method (arrow)\",\"code\":\"a -> method ()\"},{\"name\":\"procedure method 1 (dots)\",\"code\":\"a . method \"},{\"name\":\"procedure method 2 (dots)\",\"code\":\"a . method , \"},{\"name\":\"procedure method 1 (arrow)\",\"code\":\"a -> method \"},{\"name\":\"procedure method 2 (arrow)\",\"code\":\"a -> method , \"}]}","routines.definitions.1.spec.ts":"{\"suiteName\":\"Validates routine parsing\",\"fileName\":\"routines.definitions.1.spec.ts\",\"tests\":[{\"name\":\"verifies procedure with arguments and keywords\",\"code\":[\"PRO EndMagic, arg1, $ ; comment\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"END\"]},{\"name\":\"verifies functions with arguments and keywords\",\"code\":[\"function myfunc, arg1, $ ; comment\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"end\"]},{\"name\":\"verifies procedure method with arguments and keywords\",\"code\":[\"PRO myclass::mymethod, arg1, $ ; comment\",\" ; skip empty lines\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"END\"]},{\"name\":\"verifies function method with arguments and keywords\",\"code\":[\"function myfuncclass::mymethod, arg1, $ ; comment\",\"\",\" arg2, KW1 = $\",\"\",\" kw1, KW2 = kw2\",\"\",\"end\"]},{\"name\":\"verifies more than one routine\",\"code\":[\"Function f1\",\" return, 5\",\"end\",\"\",\"pro p1\",\" print, 42\",\"end\"]}]}","routines.definitions.2.spec.ts":"{\"suiteName\":\"Validates routine parsing\",\"fileName\":\"routines.definitions.2.spec.ts\",\"tests\":[{\"name\":\"verifies we only stop on \\\"end\\\"\",\"code\":[\"PRO EndMagic, Unit, Id\",\" PRINTF, Unit\",\"END\"]},{\"name\":\"verifies we parse names with \\\"!\\\"\",\"code\":[\"pro !sosobad,\",\"END\"]},{\"name\":\"verifies we parse method names with \\\"!\\\"\",\"code\":[\"pro !sosobad::method,\",\"END\"]},{\"name\":\"routines in a very bad single-line\",\"code\":\"FUNCTION VarName, Ptr & RETURN,'' & END\"}]}","string-literal.spec.ts":"{\"suiteName\":\"Verify string literal processing\",\"fileName\":\"string-literal.spec.ts\",\"tests\":[{\"name\":\"simple with substitution\",\"code\":\"a = `my string with ${expression + 5}`\"},{\"name\":\"simple without substitution\",\"code\":\"a = `my string without substitution`\"},{\"name\":\"properly capture nested literals\",\"code\":\"a = `start ${ `nested` } else`\"},{\"name\":\"complex nested case\",\"code\":\"a = `something ${func(a = b, `nested`, /kw) + 6*12} else ${5*5 + `something` + nested} some`\"},{\"name\":\"parse escaped backticks\",\"code\":\"a = `something \\\\` included `\"},{\"name\":\"preserve spacing when extracting tokens\",\"code\":\"a = ` first `\"},{\"name\":\"template literal string with formatting\",\"code\":\"a = `${1.234,\\\"%10.3f\\\"}`\"}]}","string-literal.multiline.spec.ts":"{\"suiteName\":\"Verify string literal processing with multi-line statements\",\"fileName\":\"string-literal.multiline.spec.ts\",\"tests\":[{\"name\":\"preserve spacing and handle multi-line string literals\",\"code\":[\"compile_opt idl2\",\"; thing\",\"a = ` first\",\" second\",\" third\",\"last`\",\"end\"]}]}","string-literal.escape.spec.ts":"{\"suiteName\":\"Verify string literal escape characters\",\"fileName\":\"string-literal.escape.spec.ts\",\"tests\":[{\"name\":\"for syntax highlighting\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"a = `\\\\a `\",\"end\"]}]}","structures.1.spec.ts":"{\"suiteName\":\"Validates structure parsing\",\"fileName\":\"structures.1.spec.ts\",\"tests\":[{\"name\":\"verifies simplest structure parsing\",\"code\":\"_z5$ = {thing}\"},{\"name\":\"verifies multi-line structure name parsing\",\"code\":[\"_17$ = { $\",\" thing}\"]},{\"name\":\"verifies simplest property parsing without structure name\",\"code\":\"_17$ = {thing:z}\"},{\"name\":\"verifies simplest property parsing without structure name and line continuation\",\"code\":[\"_17$ = { $\",\" thing:z}\"]},{\"name\":\"verifies simplest nested structure parsing\",\"code\":\"_z5$ = {thing1:{thing2:z}}\"},{\"name\":\"verifies structure with inheritance\",\"code\":\"_z5$ = {thing, inherits _jklol}\"},{\"name\":\"verifies all components in single-line\",\"code\":\"a17 = {_th1g, abc:def, b:5, c:f()}\"}]}","structures.2.spec.ts":"{\"suiteName\":\"Validates structure parsing\",\"fileName\":\"structures.2.spec.ts\",\"tests\":[{\"name\":\"verifies multiple structure names (even though wrong syntax)\",\"code\":\"a = {one,two,three,inherits thing, inherits other, prop:5} ; comment\"},{\"name\":\"verifies nested structures, line continuations, and comments\",\"code\":[\"_17$ = { $ ; something\",\" thing: {name, some:value}}\"]},{\"name\":\"verifies weird syntax for named structures\",\"code\":[\"new_event = {FILESEL_EVENT, parent, ev.top, 0L, $\",\"path+filename, 0L, theFilter}\"]},{\"name\":\"structure names with exclamation points\",\"code\":\"a = {!exciting}\"},{\"name\":\"structure names and then line continuation\",\"code\":\"void = {mlLabelingTool_GraphicOverlay $\"},{\"name\":\"inherits supports spaces\",\"code\":[\" void = {IDLitDataIDLArray2D, $\",\" inherits IDLitData}\"]}]}","unexpected.1.spec.ts":"{\"suiteName\":\"Validates unexpected closer parsing\",\"fileName\":\"unexpected.1.spec.ts\",\"tests\":[{\"name\":\"verifies we catch unexpected closers (other tests cover correctly catching real closers instead of these)\",\"code\":[\")\",\"]\",\"}\",\"endif\",\"endelse\",\"endfor\",\"endforeach\",\"endrep\",\"endwhile\",\"endswitch\",\"endcase\",\"end\"]}]}","unknown.spec.ts":"{\"suiteName\":\"Validates unknown token parsing\",\"fileName\":\"unknown.spec.ts\",\"tests\":[{\"name\":\"improper arrow function\",\"code\":\"sEvent.component-> $\"},{\"name\":\"text after comment\",\"code\":\"a = $ bad bad\"},{\"name\":\"unknown has right positioning with zero-width matches\",\"code\":\"scale=scale, $, $\"}]}"},"auto-textmate-tests":{"assignment.spec.ts":"{\"suiteName\":\"Validates assignment parsing\",\"fileName\":\"assignment.spec.ts\",\"tests\":[{\"name\":\"parses variable assignment\",\"code\":\"a = 5\"},{\"name\":\"parses system variable assignment\",\"code\":\"!null = 5\"},{\"name\":\"brackets with assignment\",\"code\":\"a[i] = b\"},{\"name\":\"parses variable assignment with line continuation\",\"code\":[\"z = $\",\" 5\"]},{\"name\":\"assignment with parentheses\",\"code\":\"(b) = 15\"},{\"name\":\"procedure after assignment in loop and keyword\",\"code\":\"for i=0, myFunc(a=42) do print, i\"}]}","blocks.spec.ts":"{\"suiteName\":\"Validates block parsing auto-closes\",\"fileName\":\"blocks.spec.ts\",\"tests\":[{\"name\":\"lib example from kruskal_wallis.pro\",\"code\":[\"\",\"if !true then $\",\"\",\"while !true DO BEGIN\",\" a = 42 \",\"ENDWHILE $\",\"\",\"ELSE stop = stop+1\",\"end\"]}]}","brackets.spec.ts":"{\"suiteName\":\"Validates bracket parsing\",\"fileName\":\"brackets.spec.ts\",\"tests\":[{\"name\":\"parses standalone brackets\",\"code\":\"[1 + 2]\"},{\"name\":\"parses standalone brackets with line continuations\",\"code\":[\"[1 + $\",\" 2]\"]},{\"name\":\"indexing and compound expression\",\"code\":\"array1[1 + 2] * (1 + 2)\"},{\"name\":\"brackets with assignment\",\"code\":\"_a[i] = 5 * b\"},{\"name\":\"brackets with compound assignment\",\"code\":\"_aA$[i] *= b\"}]}","colon.spec.ts":"{\"suiteName\":\"Validates colon parsing\",\"fileName\":\"colon.spec.ts\",\"tests\":[{\"name\":\"simple colon test\",\"code\":\"[:]\"},{\"name\":\"array indexing\",\"code\":\"a[0:I] = 42\"}]}","commas.spec.ts":"{\"suiteName\":\"Validates comma parsing (mostly covered elsewhere)\",\"fileName\":\"commas.spec.ts\",\"tests\":[{\"name\":\"don't find commas on their own\",\"code\":\",\"},{\"name\":\"find commas in function\",\"code\":\"f(,)\"},{\"name\":\"find commas in pro\",\"code\":\"p,\"}]}","comments.spec.ts":"{\"suiteName\":\"Validates comment parsing\",\"fileName\":\"comments.spec.ts\",\"tests\":[{\"name\":\"parses simple comments\",\"code\":\" ; something()\"},{\"name\":\"parses code with comments at the end\",\"code\":\"a = b() ; something()\"},{\"name\":\"parses simple comments with TODO\",\"code\":\" ; TODO: something()\"},{\"name\":\"parses code with comments at the end with TODO\",\"code\":\"a = b() ; TODO: something()\"},{\"name\":\"parses code with comments and line continuations\",\"code\":[\"a = $ ; TODO: something()\",\" b()\"]}]}","control.1.spec.ts":"{\"suiteName\":\"Validates control statement parsing\",\"fileName\":\"control.1.spec.ts\",\"tests\":[{\"name\":\"parses basic control statements\",\"code\":[\"break\",\"continue\",\"jump: a = func()\",\"jump: mypro, $\",\" 5\",\"jumpy17$: ;comment\"]},{\"name\":\"parses break in if statements\",\"code\":\"if !true then break\"},{\"name\":\"parses continue in if statements\",\"code\":\"if !true then continue\"},{\"name\":\"parses continue and break in loops\",\"code\":[\"for i=0,99 do begin\",\" continue\",\" break\",\"endfor\"]},{\"name\":\"parses jump in blocks\",\"code\":[\"for i=0,99 do begin\",\" jump:\",\"endfor\"]},{\"name\":\"parses compound control statements\",\"code\":[\"common, group, var1, var2, var3 ; comment\",\"compile_opt, idl2, $ ; line continuation\",\" hidden\",\"compile_opt\",\"forward_function, idl2, hidden\",\"goto, label\"]},{\"name\":\"goto in in statement\",\"code\":\"if not wild then goto, done else printf, outunit\"},{\"name\":\"statements end at line separator\",\"code\":\"GOTO, do_six & END\"}]}","executive-command.spec.ts":"{\"suiteName\":\"Validates executive command parsing\",\"fileName\":\"executive-command.spec.ts\",\"tests\":[{\"name\":\"simple 1\",\"code\":\".compile\"},{\"name\":\"simple 2\",\"code\":\".run myfile.pro\"},{\"name\":\"simple 3 start with spaces\",\"code\":\" .run myfile.pro\"},{\"name\":\"ignore methods\",\"code\":\"obj.method\"},{\"name\":\"ignore properties\",\"code\":\"!null = obj.method\"}]}","include.spec.ts":"{\"suiteName\":\"Validates include statements, but not correct location\",\"fileName\":\"include.spec.ts\",\"tests\":[{\"name\":\"basic test\",\"code\":\"@includeme\"},{\"name\":\"don't find in functions\",\"code\":\"a = myfunc(@bad)\"},{\"name\":\"find in loops\",\"code\":\"for i=0,99 do @very_wrong\"},{\"name\":\"don't find in expressions\",\"code\":\"a = @include_wrong + @way_bad\"},{\"name\":\"don't capture afterwards\",\"code\":\"@include.pro ; comment\"}]}","lambda.spec.ts":"{\"suiteName\":\"Validates lambda functions parsed as special token\",\"fileName\":\"lambda.spec.ts\",\"tests\":[{\"name\":\"correctly parse lambda functions\",\"code\":\"a = lambda(x:x+2)\"}]}","line-modifiers.spec.ts":"{\"suiteName\":\"Validates line modifier (separators)\",\"fileName\":\"line-modifiers.spec.ts\",\"tests\":[{\"name\":\"parses multi-line as single-line\",\"code\":[\"a = a + b() & proc & a.procMethod,1 & $\",\"a={struct}\"]},{\"name\":\"loops properly stop in line modifier\",\"code\":[\"proc & for i=0,99 do print, i & while !true do b = awesome() & foreach val, b, key do print, key, val & endedit\"]},{\"name\":\"line separators in case statement\",\"code\":[\"CASE typ OF\",\" 7: begin val = \\\"\\\" & cnt = 1 & endcase\",\" 8: val = tiff_sint(val, 0, len=cnt)\",\"ENDCASE\"]},{\"name\":\"verifies nested line continuations use basic token\",\"code\":\"scale=scale, $, $\"}]}","logic.if-then-else.1.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [1]\",\"fileName\":\"logic.if-then-else.1.spec.ts\",\"tests\":[{\"name\":\"parses basic if-then loop\",\"code\":\"if !true then print, 'yes'\"},{\"name\":\"parses basic if-then-else loop\",\"code\":\"if ~doIt then print, 'yes' else a = yellow()\"},{\"name\":\"parses basic if-then loop with line continuation 1\",\"code\":[\"if !true $\",\" then print, 'yes'\"]},{\"name\":\"parses basic if-then loop with line continuation 2\",\"code\":[\"if !true $\",\" then print $\",\" , 'yes'\"]},{\"name\":\"parses basic if-then-else loop with line continuation 1\",\"code\":[\"if !true then print, 'yes' $\",\" else print, 'no'\"]},{\"name\":\"parses basic if-then-else loop with line continuation 2\",\"code\":[\"if !true then print, 'yes' $\",\" else $\",\" print, 'no'\"]},{\"name\":\"nested if-then-else\",\"code\":\"if ~(myFunc(_a17$) * 2) then if !false then print, 'yes'\"}]}","logic.if-then-else.2.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [2]\",\"fileName\":\"logic.if-then-else.2.spec.ts\",\"tests\":[{\"name\":\"with blocks [1]\",\"code\":[\"if a++ then begin\",\" super = awesome()\",\"endif else print, 'else'\"]}]}","logic.if-then-else.3.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [3]\",\"fileName\":\"logic.if-then-else.3.spec.ts\",\"tests\":[{\"name\":\"example from IDL code [1]\",\"code\":\"if i ne 0 then a[0, m1-i] = y ;Symmetrical\"},{\"name\":\"example from IDL code [2]\",\"code\":[\"if (ISA(equation)) then begin\",\" graphic.SetProperty, EQUATION=equation\",\" arg1 = equation\",\" if (ISA(style)) then arg2 = style\",\"endif\"]},{\"name\":\"example from IDL code [3]\",\"code\":[\"IF (nms[i-1, j] && ~marked[i-1, j]) THEN $\",\" canny_follow, i-1, j, nms, marked\"]},{\"name\":\"example from IDL code [4]\",\"code\":[\"IF (max(step) && ~n_elements(stepflag)) THEN $\",\" suppMag = nmsupp_mask * mag\"]},{\"name\":\"example from IDL code [5]\",\"code\":[\"if (~Isa(hDefinition, 'Hash') || $\",\" ~hDefinition.HasKey('schema') || $\",\" ~(hDefinition['schema']).StartsWith('IDLColorGradientDefinition', /FOLD_CASE)) then begin\",\" message, 'File does not contain a valid color gradient definition.', /NONAME \",\"endif\"]}]}","logic.case.1.spec.ts":"{\"suiteName\":\"Validates case statement\",\"fileName\":\"logic.case.1.spec.ts\",\"tests\":[{\"name\":\"parses case loop with many syntaxes\",\"code\":[\"CASE x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\"ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDCASE\"]},{\"name\":\"nested case statement\",\"code\":[\"CASE x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" CASE x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDCASE\",\"END\",\"ENDCASE\"]}]}","logic.switch.1.spec.ts":"{\"suiteName\":\"Validates switch statement\",\"fileName\":\"logic.switch.1.spec.ts\",\"tests\":[{\"name\":\"parses switch loop with many syntaxes\",\"code\":[\"SWITCH x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\"ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDSWITCH\"]},{\"name\":\"nested switch statement\",\"code\":[\"SWITCH x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" SWITCH x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDSWITCH\",\"END\",\"ENDSWITCH\"]}]}","logic.ternary.1.spec.ts":"{\"suiteName\":\"Validates for ternary statement parsing\",\"fileName\":\"logic.ternary.1.spec.ts\",\"tests\":[{\"name\":\"simplest ternary statement\",\"code\":\"a = something ? 5 : 6\"},{\"name\":\"nested ternary statement grouped\",\"code\":\"a = !true ? (!false ? 7 : 8) : 6\"},{\"name\":\"nested ternary statement without grouping\",\"code\":\"mypro, something ? ~something ? 7 : 8 : 6, 2\"},{\"name\":\"ternary as argument\",\"code\":\"a = myfunc(something ? otherfunc() : !awesomesauce) + 3\"},{\"name\":\"operators end on ternary statements\",\"code\":\"a = 5*something ? 5- 4 : 6^3\"},{\"name\":\"multi-line ternary 1\",\"code\":[\"a = _myvar $\",\" ? 'jello' : \\\"jelly\\\"\"]},{\"name\":\"multi-line ternary 2\",\"code\":[\"a = myfunc( $\",\" a,b,c) ? b4d $\",\" : $\",\" s1nt4x3x4mple\"]},{\"name\":\"ternary works in braces as expected\",\"code\":[\"_17 = arr[!true ? 0 : -3: -1]\"]}]}","loops.for.spec.ts":"{\"suiteName\":\"Validates for loop parsing\",\"fileName\":\"loops.for.spec.ts\",\"tests\":[{\"name\":\"parses basic for loop\",\"code\":\"for i=0, 99 do print, i\"},{\"name\":\"parses basic for loop with increment\",\"code\":\"for i=0, 99, 2 do !null = myFunc(i)\"},{\"name\":\"parses basic for loop with line continuation\",\"code\":[\"for i=0, jj do $\",\" print, i\"]},{\"name\":\"parses basic for loop with block\",\"code\":[\"for i=0, 99 do begin\",\" !null = myFunc(i)\",\"endfor\"]},{\"name\":\"parses nested for loop\",\"code\":\"for i=0, 99 do for j=0, 99 do print, i + j\"}]}","loops.foreach.spec.ts":"{\"suiteName\":\"Validates foreach loop parsing\",\"fileName\":\"loops.foreach.spec.ts\",\"tests\":[{\"name\":\"parses basic foreach loop\",\"code\":\"foreach val, arr do print, i\"},{\"name\":\"parses basic foreach loop with key\",\"code\":\"foreach val, arr, idx do !null = myFunc(i)\"},{\"name\":\"parses basic foreach loop with line continuation\",\"code\":[\"foreach val, arr do $\",\" print, i\"]},{\"name\":\"parses basic foreach loop with block\",\"code\":[\"foreach val, arr do begin\",\" !null = myFunc(i)\",\"endforeach\"]},{\"name\":\"parses nested foreach loop\",\"code\":\"foreach val, arr do foreach val2, val do print, val2\"}]}","loops.repeat.spec.ts":"{\"suiteName\":\"Validates repeat loop parsing\",\"fileName\":\"loops.repeat.spec.ts\",\"tests\":[{\"name\":\"parses basic repeat loop\",\"code\":\"REPEAT A = A * 2 UNTIL A GT B\"},{\"name\":\"parses procedure in repeat loop\",\"code\":\"REPEAT PRINT, A UNTIL A GT B\"},{\"name\":\"parses basic repeat loop with line continuations\",\"code\":[\"REPEAT A = $\",\" A * 2 UNTIL $\",\" A GT B\"]},{\"name\":\"parses basic repeat loop with block\",\"code\":[\"REPEAT BEGIN\",\" A = A * 2\",\"ENDREP UNTIL A GT B\"]},{\"name\":\"correctly parses loops with if statements inside\",\"code\":[\"repeat if !true then break until !true\"]}]}","loops.while.spec.ts":"{\"suiteName\":\"Validates while loop parsing\",\"fileName\":\"loops.while.spec.ts\",\"tests\":[{\"name\":\"parses basic while loop\",\"code\":\"while !true do print, i\"},{\"name\":\"parses basic nested while loop\",\"code\":\"while !true do while !false do print, i\"},{\"name\":\"parses basic while loop with line continuation\",\"code\":[\"while !true do $\",\" print, $\",\" i\"]},{\"name\":\"parses basic while loop with block\",\"code\":[\"while (a eq 5) do begin\",\" !null = myFunc(i)\",\"endwhile\"]}]}","methods.functions.spec.ts":"{\"suiteName\":\"Validates function method parsing\",\"fileName\":\"methods.functions.spec.ts\",\"tests\":[{\"name\":\"parses function methods with dots\",\"code\":\"!NULL = a.myFunc(1)\"},{\"name\":\"parses function methods with arrows\",\"code\":\"!NULL = a->myFunc(1)\"},{\"name\":\"parses super function methods with dots\",\"code\":\"a.super::myfunc(1)\"},{\"name\":\"parses super function methods with arrows\",\"code\":\"a->super::myfunc(a)\"},{\"name\":\"parses function methods with dots and line continuation\",\"code\":[\"!NULL = a.myFunc( $\",\" 1)\"]},{\"name\":\"single-character function method\",\"code\":\"a.b()\"}]}","methods.procedures.spec.ts":"{\"suiteName\":\"Validates procedure method parsing\",\"fileName\":\"methods.procedures.spec.ts\",\"tests\":[{\"name\":\"parses procedure methods with dots\",\"code\":\"a.myProc, 1\"},{\"name\":\"parses procedure methods with arrows\",\"code\":\"a->myProc, a\"},{\"name\":\"parses super procedure methods with dots\",\"code\":\"a.super::myProc, 1\"},{\"name\":\"parses super procedure methods with arrows\",\"code\":\"a->super::myProc, a\"},{\"name\":\"parses procedure methods with dots and line continuations\",\"code\":[\"a.myProc, $\",\" 1\"]},{\"name\":\"procedure method from IDL lib\",\"code\":[\"((*state).markers).Add, CGRAD_NEW_MARKER(POSITION=marker['position'], $\",\" COLOR=color, $\",\" MIDDLE=marker['middle'])\"]},{\"name\":\"single-character procedure method\",\"code\":\"a.b\"}]}","numbers.spec.ts":"{\"suiteName\":\"Validates special cases for number parsing\",\"fileName\":\"numbers.spec.ts\",\"tests\":[{\"name\":\"correctly parse scientific notations\",\"code\":[\"a = -1e34\",\"a = -1e34i\",\"a = -1e34j\"]},{\"name\":\"correctly parse scientific notations with negatives 1\",\"code\":[\"a = 1e-34\",\"a = 1e-34i\",\"a = 1e-34j\"]},{\"name\":\"correctly parse scientific notations with negatives 2\",\"code\":[\"a = 1e-\",\"a = 1e-i\",\"a = 1e-j\"]},{\"name\":\"correctly parse hex notation\",\"code\":[\"a = 0x8FFF + 0x8Fub + 0x8FulL\",\"a = 0x8FFFI + 0x8FubI + 0x8FulLi\",\"a = 0x8FFFJ + 0x8Fubj + 0x8FulLJ\"]},{\"name\":\"correctly parse octal notation\",\"code\":[\"a = 0o8FFF + 0o8Fub + 0o8FulL\",\"a = 0o8FFFI + 0o8FubI + 0o8FulLi\",\"a = 0o8FFFJ + 0o8Fubj + 0o8FulLJ\"]},{\"name\":\"correctly parse binary notation\",\"code\":[\"a = 0b8FFF + 0b8Fub + 0b8FulL\",\"a = 0b8FFFI + 0b8FubI + 0b8FulLi\",\"a = 0b8FFFJ + 0b8Fubj + 0b8FulLJ\"]},{\"name\":\"correctly parse scientific notations with doubles\",\"code\":[\"a = -1d34\",\"a = -1d34i\",\"a = -1d34j\"]},{\"name\":\"correctly parse scientific notations with doubles with negatives 1\",\"code\":[\"a = 1d-34\",\"a = 1d-34i\",\"a = 1d-34j\"]},{\"name\":\"correctly parse scientific notations with doubles with negatives 2\",\"code\":[\"a = 1d-\",\"a = 1d-i\",\"a = 1d-j\"]},{\"name\":\"correctly parse new syntax for complex\",\"code\":[\"a = 1i\",\"a = 1j\"]},{\"name\":\"catch unfinished dot statement 1\",\"code\":\"a.\"},{\"name\":\"catch unfinished dot statement 2\",\"code\":\"a = b.\"},{\"name\":\"catch standalone dot\",\"code\":\"a = .\"},{\"name\":\"edge case scientific\",\"code\":\"a = .1e+12\"},{\"name\":\"solo dot\",\"code\":\".\"}]}","number-string.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36 + \\\"45\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36b + \\\"45ull\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'b\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'x\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'o\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"b\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"x\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"o\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XS\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XS\"}]}","number-string.complex-i.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.complex-i.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36i + \\\"45i\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36bi + \\\"45ulli\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'bi\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'xi\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'oi\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"bi\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"xi\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"oi\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XSi\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XSi\"}]}","number-string.complex-j.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.complex-j.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36j + \\\"45j\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36bj + \\\"45ullj\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'bj\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'xj\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'oj\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"bj\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"xj\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"oj\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XSj\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XSj\"}]}","operators.compound.spec.ts":"{\"suiteName\":\"Validates compound operator parsing\",\"fileName\":\"operators.compound.spec.ts\",\"tests\":[{\"name\":\"parses with line continuation\",\"code\":[\"z *= $\",\" 5\"]},{\"name\":\"does not recurse with \\\"||\\\" operator\",\"code\":\"a || b || c\"},{\"name\":\"does not recurse with \\\"or\\\" operator\",\"code\":\"a or b or c\"},{\"name\":\"captures all statements with \\\"&&\\\" operator\",\"code\":\"a && b && c\"},{\"name\":\"captures all statements with \\\"&&\\\" operator\",\"code\":\"a and b and c\"}]}","operators.spec.ts":"{\"suiteName\":\"Validates operator parsing\",\"fileName\":\"operators.spec.ts\",\"tests\":[{\"name\":\"close on braces\",\"code\":\"{1+2}\"},{\"name\":\"close on brackets\",\"code\":\"[1+2]\"},{\"name\":\"close on parentheses\",\"code\":\"(1+2)\"},{\"name\":\"close on commas\",\"code\":\"1+2,3+4\"},{\"name\":\"close on then and else\",\"code\":\"if 1+2 then a = 3+4 else a = 4^3\"},{\"name\":\"close on do in loops\",\"code\":\"for i=0, 99-1 do print, i\"},{\"name\":\"operators with line continuations\",\"code\":[\"zach + $ \",\"awesome\"]},{\"name\":\"operators end on \\\"of\\\"\",\"code\":[\"case n_params()-1 of\",\" 0: call_method, method_name, oObj[i], _extra=e\",\" 1: call_method, method_name, oObj[i], p1, _extra=e\",\"endcase\"]},{\"name\":\"operators end on arrow function\",\"code\":\"*(*pState).pTitle->SetProperty, color=[255, 255, 255]\"},{\"name\":\"operators end on procedure method\",\"code\":\"*pTitle.SetProperty, color=[255, 255, 255]\"},{\"name\":\"operators do not end on function method\",\"code\":\"*pTitle.SetProperty(color=[255, 255, 255])\"},{\"name\":\"operators do not end on function method\",\"code\":\"*pTitle->SetProperty(color=[255, 255, 255])\"},{\"name\":\"special token for increment\",\"code\":[\"++a\",\"a++\"]},{\"name\":\"special token for decrement\",\"code\":[\"--a\",\"a+--\"]},{\"name\":\"next to each other\",\"code\":\"a = b++ + 5\"}]}","parentheses.spec.ts":"{\"suiteName\":\"Validates parentheses parsing\",\"fileName\":\"parentheses.spec.ts\",\"tests\":[{\"name\":\"parses standalone parentheses\",\"code\":\"(1 + 2)\"},{\"name\":\"separate function from parentheses\",\"code\":\"myFunc(1 + 2) * (1 + 2)\"},{\"name\":\"parses standalone parentheses with line continuation\",\"code\":[\"(1 + $ \",\" 2)\"]}]}","prompts.spec.ts":"{\"suiteName\":\"Validates prompt parsing\",\"fileName\":\"prompts.spec.ts\",\"tests\":[{\"name\":\"parses IDL prompt\",\"code\":\"IDL> print, 42\"},{\"name\":\"parses ENVI prompt\",\"code\":\"ENVI> print, 17\"}]}","properties.spec.ts":"{\"suiteName\":\"Validates property parsing\",\"fileName\":\"properties.spec.ts\",\"tests\":[{\"name\":\"parses property assignment\",\"code\":\"a.thing = 5\"},{\"name\":\"parses property access\",\"code\":\"b = a.thing\"},{\"name\":\"parses property access with line continuation\",\"code\":[\"b = $\",\" a.thing\"]},{\"name\":\"parses nested property access\",\"code\":\"b = a.thing1.thing2\"},{\"name\":\"parses property access as arguments\",\"code\":\"myPro, a.thing, b.thing\"},{\"name\":\"property example from IDL lib\",\"code\":\"(*state).bottomSelection = lMarkers.Count()-1\"},{\"name\":\"structure property via indexing\",\"code\":\"a = b.(i)\"}]}","python.spec.ts":"{\"suiteName\":\"Validates Python code parsing\",\"fileName\":\"python.spec.ts\",\"tests\":[{\"name\":\"parses IDL prompt\",\"code\":\">>>import numpy as np\"}]}","quotes.spec.ts":"{\"suiteName\":\"Validates quote parsing\",\"fileName\":\"quotes.spec.ts\",\"tests\":[{\"name\":\"parses standalone single quotes\",\"code\":\"'myFunc(1 + 2)'\"},{\"name\":\"parses standalone double quotes\",\"code\":\"\\\"myFunc(1 + 2)\\\"\"},{\"name\":\"verify single quotes without closing\",\"code\":\"'string\"},{\"name\":\"verify double quotes without closing\",\"code\":\"\\\"string\"},{\"name\":\"confusing single quote\",\"code\":\"hDefinition['schema']).StartsWith('IDLColorGradientDefinition', /FOLD_CASE)\"},{\"name\":\"confusing double quote\",\"code\":\"hDefinition[\\\"schema\\\"]).StartsWith(\\\"IDLColorGradientDefinition\\\", /FOLD_CASE)\"},{\"name\":\"quotes end at important statements 1\",\"code\":[\"if \\\"bad-quote\\\"then \\\"bad-quote\\\"else\"]},{\"name\":\"quotes end at important statements 2\",\"code\":[\"case \\\"bad-quote\\\"of\"]},{\"name\":\"quotes end at important statements 3\",\"code\":[\"for \\\"bad-quote\\\"do\"]},{\"name\":\"quotes end at important statements 4\",\"code\":[\"repeat 'bad-quote'until\"]},{\"name\":\"quotes end at important statements 5\",\"code\":[\"if 'bad-quote'then 'bad-quote'else\"]},{\"name\":\"quotes end at important statements 6\",\"code\":[\"case 'bad-quote'of\"]},{\"name\":\"quotes end at important statements 7\",\"code\":[\"for 'bad-quote'do\"]},{\"name\":\"quotes end at important statements 8\",\"code\":[\"repeat 'bad-quote'until\"]},{\"name\":\"verifies quote vs number is correctly identified\",\"code\":[\"arr = [\\\"0.00000000\\\"]\"]}]}","quotes.escaped.spec.ts":"{\"suiteName\":\"Validates escaped quote parsing\",\"fileName\":\"quotes.escaped.spec.ts\",\"tests\":[{\"name\":\"simple single quote\",\"code\":\"'Resolve_Routine, ''%s'', Is_Function=%d'\"},{\"name\":\"simple double quote\",\"code\":\"\\\"Resolve_Routine, \\\"\\\"%s\\\"\\\", Is_Function=%d\\\"\"},{\"name\":\"complex single quote\",\"code\":\"'Resolve_Routine, ''%s'', Is_Function=%d''lots of''other''string'\"},{\"name\":\"complex double quote\",\"code\":\"\\\"Resolve_Routine, \\\"\\\"%s\\\"\\\", Is_Function=%d\\\"\\\"lots of\\\"\\\"other\\\"\\\"string\\\"\"}]}","quotes.edge-cases.spec.ts":"{\"suiteName\":\"Validates edge case quote parsing\",\"fileName\":\"quotes.edge-cases.spec.ts\",\"tests\":[{\"name\":\"for number-string like strings\",\"code\":\"a = \\\"5\\\"\"}]}","routines.functions.spec.ts":"{\"suiteName\":\"Validates function parsing\",\"fileName\":\"routines.functions.spec.ts\",\"tests\":[{\"name\":\"parses standalone functions\",\"code\":\"myFunc(1 + 2)\"},{\"name\":\"parses nested functions\",\"code\":\"myFunc(myFunc2(_y7$) + 2)\"},{\"name\":\"separate function from parentheses\",\"code\":\"myFunc(1 + 2) * (1 + 2)\"},{\"name\":\"parses standalone functions with line continuations\",\"code\":[\"myFunc(1 $\",\" + 2)\"]},{\"name\":\"single-character function\",\"code\":\"a()\"}]}","routines.keywords.spec.ts":"{\"suiteName\":\"Validates keyword parsing\",\"fileName\":\"routines.keywords.spec.ts\",\"tests\":[{\"name\":\"parses keyword assignment\",\"code\":\"myfunc(a = 5)\"},{\"name\":\"parses multiple keywords\",\"code\":\"_otherfunc(a = 5, _b=42)\"},{\"name\":\"parses multiple keywords with line continuation\",\"code\":[\"myfunc(a = 5, $\",\" _b=42)\"]},{\"name\":\"parses keyword assignment with line continuation\",\"code\":[\"myfunc(a $\",\" = 5)\"]},{\"name\":\"parses variable assignment\",\"code\":\"_y = _superFunction(a = 5)\"}]}","routines.procedures.spec.ts":"{\"suiteName\":\"Validates procedure parsing\",\"fileName\":\"routines.procedures.spec.ts\",\"tests\":[{\"name\":\"parses standalone procedures\",\"code\":\"myPro, 1 + 2\"},{\"name\":\"separate pro from variables\",\"code\":\"myPro, arg1, arg2\"},{\"name\":\"pro with line continuations\",\"code\":[\"myPro, $\",\" arg1, arg2\"]},{\"name\":\"pro in loop after arguments and function\",\"code\":\"for i=0, 2*5-jello(1) do print, i\"},{\"name\":\"single-character procedure\",\"code\":\"a\"}]}","routines.spacing.spec.ts":"{\"suiteName\":\"Validates routine spacing\",\"fileName\":\"routines.spacing.spec.ts\",\"tests\":[{\"name\":\"functions\",\"code\":\"myFunc (1 + 2)\"},{\"name\":\"procedures\",\"code\":\"mypro ,\"},{\"name\":\"function method (dots)\",\"code\":\"a . method ()\"},{\"name\":\"function method (arrow)\",\"code\":\"a -> method ()\"},{\"name\":\"procedure method 1 (dots)\",\"code\":\"a . method \"},{\"name\":\"procedure method 2 (dots)\",\"code\":\"a . method , \"},{\"name\":\"procedure method 1 (arrow)\",\"code\":\"a -> method \"},{\"name\":\"procedure method 2 (arrow)\",\"code\":\"a -> method , \"}]}","routines.definitions.1.spec.ts":"{\"suiteName\":\"Validates routine parsing\",\"fileName\":\"routines.definitions.1.spec.ts\",\"tests\":[{\"name\":\"verifies procedure with arguments and keywords\",\"code\":[\"PRO EndMagic, arg1, $ ; comment\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"END\"]},{\"name\":\"verifies functions with arguments and keywords\",\"code\":[\"function myfunc, arg1, $ ; comment\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"end\"]},{\"name\":\"verifies procedure method with arguments and keywords\",\"code\":[\"PRO myclass::mymethod, arg1, $ ; comment\",\" ; skip empty lines\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"END\"]},{\"name\":\"verifies function method with arguments and keywords\",\"code\":[\"function myfuncclass::mymethod, arg1, $ ; comment\",\"\",\" arg2, KW1 = $\",\"\",\" kw1, KW2 = kw2\",\"\",\"end\"]},{\"name\":\"verifies more than one routine\",\"code\":[\"Function f1\",\" return, 5\",\"end\",\"\",\"pro p1\",\" print, 42\",\"end\"]}]}","routines.definitions.2.spec.ts":"{\"suiteName\":\"Validates routine parsing\",\"fileName\":\"routines.definitions.2.spec.ts\",\"tests\":[{\"name\":\"verifies we only stop on \\\"end\\\"\",\"code\":[\"PRO EndMagic, Unit, Id\",\" PRINTF, Unit\",\"END\"]},{\"name\":\"verifies we parse names with \\\"!\\\"\",\"code\":[\"pro !sosobad,\",\"END\"]},{\"name\":\"verifies we parse method names with \\\"!\\\"\",\"code\":[\"pro !sosobad::method,\",\"END\"]},{\"name\":\"routines in a very bad single-line\",\"code\":\"FUNCTION VarName, Ptr & RETURN,'' & END\"}]}","string-literal.spec.ts":"{\"suiteName\":\"Verify string literal processing\",\"fileName\":\"string-literal.spec.ts\",\"tests\":[{\"name\":\"simple with substitution\",\"code\":\"a = `my string with ${expression + 5}`\"},{\"name\":\"simple without substitution\",\"code\":\"a = `my string without substitution`\"},{\"name\":\"properly capture nested literals\",\"code\":\"a = `start ${ `nested` } else`\"},{\"name\":\"complex nested case\",\"code\":\"a = `something ${func(a = b, `nested`, /kw) + 6*12} else ${5*5 + `something` + nested} some`\"},{\"name\":\"parse escaped backticks\",\"code\":\"a = `something \\\\` included `\"},{\"name\":\"preserve spacing when extracting tokens\",\"code\":\"a = ` first `\"},{\"name\":\"template literal string with formatting\",\"code\":\"a = `${1.234,\\\"%10.3f\\\"}`\"}]}","string-literal.multiline.spec.ts":"{\"suiteName\":\"Verify string literal processing with multi-line statements\",\"fileName\":\"string-literal.multiline.spec.ts\",\"tests\":[{\"name\":\"preserve spacing and handle multi-line string literals\",\"code\":[\"compile_opt idl2\",\"; thing\",\"a = ` first\",\" second\",\" third\",\"last`\",\"end\"]}]}","string-literal.escape.spec.ts":"{\"suiteName\":\"Verify string literal escape characters\",\"fileName\":\"string-literal.escape.spec.ts\",\"tests\":[{\"name\":\"for syntax highlighting\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"a = `\\\\a `\",\"end\"]}]}","structures.1.spec.ts":"{\"suiteName\":\"Validates structure parsing\",\"fileName\":\"structures.1.spec.ts\",\"tests\":[{\"name\":\"verifies simplest structure parsing\",\"code\":\"_z5$ = {thing}\"},{\"name\":\"verifies multi-line structure name parsing\",\"code\":[\"_17$ = { $\",\" thing}\"]},{\"name\":\"verifies simplest property parsing without structure name\",\"code\":\"_17$ = {thing:z}\"},{\"name\":\"verifies simplest property parsing without structure name and line continuation\",\"code\":[\"_17$ = { $\",\" thing:z}\"]},{\"name\":\"verifies simplest nested structure parsing\",\"code\":\"_z5$ = {thing1:{thing2:z}}\"},{\"name\":\"verifies structure with inheritance\",\"code\":\"_z5$ = {thing, inherits _jklol}\"},{\"name\":\"verifies all components in single-line\",\"code\":\"a17 = {_th1g, abc:def, b:5, c:f()}\"}]}","structures.2.spec.ts":"{\"suiteName\":\"Validates structure parsing\",\"fileName\":\"structures.2.spec.ts\",\"tests\":[{\"name\":\"verifies multiple structure names (even though wrong syntax)\",\"code\":\"a = {one,two,three,inherits thing, inherits other, prop:5} ; comment\"},{\"name\":\"verifies nested structures, line continuations, and comments\",\"code\":[\"_17$ = { $ ; something\",\" thing: {name, some:value}}\"]},{\"name\":\"verifies weird syntax for named structures\",\"code\":[\"new_event = {FILESEL_EVENT, parent, ev.top, 0L, $\",\"path+filename, 0L, theFilter}\"]},{\"name\":\"structure names with exclamation points\",\"code\":\"a = {!exciting}\"},{\"name\":\"structure names and then line continuation\",\"code\":\"void = {mlLabelingTool_GraphicOverlay $\"},{\"name\":\"inherits supports spaces\",\"code\":[\" void = {IDLitDataIDLArray2D, $\",\" inherits IDLitData}\"]}]}","unexpected.1.spec.ts":"{\"suiteName\":\"Validates unexpected closer parsing\",\"fileName\":\"unexpected.1.spec.ts\",\"tests\":[{\"name\":\"verifies we catch unexpected closers (other tests cover correctly catching real closers instead of these)\",\"code\":[\")\",\"]\",\"}\",\"endif\",\"endelse\",\"endfor\",\"endforeach\",\"endrep\",\"endwhile\",\"endswitch\",\"endcase\",\"end\"]}]}","unknown.spec.ts":"{\"suiteName\":\"Validates unknown token parsing\",\"fileName\":\"unknown.spec.ts\",\"tests\":[{\"name\":\"improper arrow function\",\"code\":\"sEvent.component-> $\"},{\"name\":\"text after comment\",\"code\":\"a = $ bad bad\"},{\"name\":\"unknown has right positioning with zero-width matches\",\"code\":\"scale=scale, $, $\"}]}"},"auto-post-processor-tests":{"arg-defs.spec.ts":"{\"suiteName\":\"Correctly extract argument definitions from code\",\"fileName\":\"arg-defs.spec.ts\",\"tests\":[{\"name\":\"Convert variables to arguments in standard routine definitions\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"Convert variables to arguments in routine method definition\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]}]}","arrows.spec.ts":"{\"suiteName\":\"Correctly map arrows\",\"fileName\":\"arrows.spec.ts\",\"tests\":[{\"name\":\"as procedure-method, but incomplete\",\"code\":[\"compile_opt idl2\",\"a->\",\"end\"]},{\"name\":\"as function method, but incomplete\",\"code\":[\"compile_opt idl2\",\"a = b->\",\"end\"]}]}","comment-blocks.1.spec.ts":"{\"suiteName\":\"Correctly map comments to comment blocks\",\"fileName\":\"comment-blocks.1.spec.ts\",\"tests\":[{\"name\":\"ignore normal comments\",\"code\":[\"compile_opt idl2\",\"; i am properly ignored like i should be\",\"a = 5\",\"end\"]},{\"name\":\"single-line blocks\",\"code\":[\"compile_opt idl2\",\";+ i am a basic block on only one line\",\"a = 5\",\"end\"]},{\"name\":\"multi-line blocks without end\",\"code\":[\"compile_opt idl2\",\";+\",\"; something about docs\",\"; like, really cool information\",\"a = 5\",\"end\"]},{\"name\":\"multi-line blocks with close\",\"code\":[\"compile_opt idl2\",\";+\",\"; worlds greatest documenter\",\";- ended\",\"a = 5\",\"end\"]},{\"name\":\"multi-line blocks with close\",\"code\":[\"compile_opt idl2\",\";+ definition of life\",\"a = 42\",\";+ second definition of life\",\"fortyTwo = 42\",\"end\"]}]}","comment-blocks.2.spec.ts":"{\"suiteName\":\"Advanced comment block cases\",\"fileName\":\"comment-blocks.2.spec.ts\",\"tests\":[{\"name\":\"end on block end and dont include excess comments\",\"code\":[\"compile_opt idl2\",\";+\",\"; worlds greatest documenter\",\";-\",\"; not included in block\",\"a = 5\",\"end\"]},{\"name\":\"allow two blocks next to each other\",\"code\":[\"compile_opt idl2\",\";+\",\"; first block\",\";-\",\";+\",\"; second block\",\";-\",\"a = 5\",\"end\"]},{\"name\":\"capture recursive blocks\",\"code\":[\"compile_opt idl2\",\";+\",\"; first block\",\";-\",\"\",\"if !true then begin\",\" ;+\",\" ; second block\",\" ;-\",\" a = 5\",\"endif\",\"\",\"end\"]}]}","comment-blocks.3.spec.ts":"{\"suiteName\":\"Confusing comment blocks \",\"fileName\":\"comment-blocks.3.spec.ts\",\"tests\":[{\"name\":\"ignore markdown lists\",\"code\":[\"compile_opt idl2\",\";+\",\"; worlds greatest documenter\",\"; - some bulleted list\",\"; - some bulleted list\",\";-\",\"a = 5\",\"end\"]}]}","control-options.spec.ts":"{\"suiteName\":\"Correctly map options for compound control statements\",\"fileName\":\"control-options.spec.ts\",\"tests\":[{\"name\":\"Convert variables to control options\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" common blockName ; ignore for now\",\" forward_function myfunc1, myfunc2, myfunc3\",\" goto, stmnt\",\"\",\"end\"]}]}","dot.spec.ts":"{\"suiteName\":\"Correctly map periods to dots\",\"fileName\":\"dot.spec.ts\",\"tests\":[{\"name\":\"as procedure-method or property access, but incomplete\",\"code\":[\"compile_opt idl2\",\"a.\",\"end\"]},{\"name\":\"as function method or property access, but incomplete\",\"code\":[\"compile_opt idl2\",\"a = b.\",\"end\"]},{\"name\":\"standalone 1\",\"code\":[\"compile_opt idl2\",\"a = .\",\"end\"]},{\"name\":\"standalone 2\",\"code\":[\"compile_opt idl2\",\".\",\"end\"]}]}","keywords.spec.ts":"{\"suiteName\":\"Correctly extract keyword names from routine calls\",\"fileName\":\"keywords.spec.ts\",\"tests\":[{\"name\":\"Convert variables to keywords when calling procedures\",\"code\":[\"compile_opt idl2\",\"mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\"\",\"end\"]},{\"name\":\"Convert variables to keywords when calling procedure methods\",\"code\":[\"compile_opt idl2\",\"obj.method, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\"\",\"end\"]},{\"name\":\"Convert variables to keywords when calling functions\",\"code\":[\"compile_opt idl2\",\"res = mypro(arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3)\",\"\",\"end\"]},{\"name\":\"Convert variables to keywords when calling function methods\",\"code\":[\"compile_opt idl2\",\"res = obj.method(arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3)\",\"\",\"end\"]}]}","keywords-binary.spec.ts":"{\"suiteName\":\"Correctly detect binary keywords\",\"fileName\":\"keywords-binary.spec.ts\",\"tests\":[{\"name\":\"in procedure\",\"code\":\"mypro, /kw1, /KW2\"},{\"name\":\"in procedure method\",\"code\":[\"myclass.method, $\",\" /KW3, KW=!true\"]},{\"name\":\"in function\",\"code\":\"a = myfunc(/KW1, /KW2)\"},{\"name\":\"in function method\",\"code\":[\"ZACH = AWESOME.SAUCE(/kw3, $\",\"/KW17, KW18 = !false)\"]},{\"name\":\"preserve other children after keyword\",\"code\":[\"compile_opt idl2\",\"tvcrs,x,y,/dev $\\t;Restore cursor\",\" kw=2\",\"\",\"end\"]},{\"name\":\"properly handle comments in function calls\",\"code\":[\"compile_opt idl2\",\"wDatatable = WIDGET_TABLE(id_datarow, $\",\"; FORMAT='(A)', $\",\" /RESIZEABLE_COLUMNS)\",\"\",\"end\"]}]}","keyword-defs.spec.ts":"{\"suiteName\":\"Correctly extract keyword definitions\",\"fileName\":\"keyword-defs.spec.ts\",\"tests\":[{\"name\":\"Convert variables to keywords in standard routine definitions\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"Convert variables to keywords in routine method definition\",\"code\":[\"pro mypro::mymethod, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"from complex example\",\"code\":[\"function TS_HANTS2, timeseries, $\",\"amplitudes = amp, $\",\"delta = delta, $\",\"dod = dod, $\",\"double = double, $\",\"err_tolerance = err_tolerance, $\",\"; FREQUENCIES=freq, $\",\"HIGH = HIGH, $\",\"low = low, $\",\"num_frequencies = num_frequencies, $\",\"num_period = num_period, $\",\"phases = phases, $\",\"range_maximum = range_maximum, $\",\"range_minimum = range_minimum, $\",\"time_sample = time_sample, $\",\"num_images = num_images\",\"\",\"compile_opt idl2\",\"\",\"a = IDL_Number.total()\",\"\",\"return, name\",\"end\"]}]}","main.spec.ts":"{\"suiteName\":\"Correctly maps main level tokens\",\"fileName\":\"main.spec.ts\",\"tests\":[{\"name\":\"do nothing without main level\",\"code\":[\"function myfunc\",\"compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"process single-line code 1\",\"code\":[\"a = plot(/TEST)\"]},{\"name\":\"process single-line code 2\",\"code\":[\"a = `${42, '42'}${42, '42'}`\"]},{\"name\":\"catch correct\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\"]},{\"name\":\"catch with no end\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\"]},{\"name\":\"catch with statements after the end\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\",\"; bad comment\",\"something = else\"]},{\"name\":\"ignore only comments\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"; another comment\"]},{\"name\":\"edge case\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"!null = myfunc()\"]}]}","operator.pointer-deref.basic.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.basic.spec.ts\",\"tests\":[{\"name\":\"ignore multiplication\",\"code\":[\"a = 6 * 7\"]},{\"name\":\"ignore multiplication\",\"code\":[\"a = (6) * (7)\"]},{\"name\":\"assignment\",\"code\":[\"a = *var\"]},{\"name\":\"after operators\",\"code\":[\"a = 5 + *var\"]},{\"name\":\"after mod operator\",\"code\":[\"a = mod *var\"]},{\"name\":\"after logical operators\",\"code\":[\"a = 5 le *var\"]},{\"name\":\"single line\",\"code\":[\"*ptr = 42\"]}]}","operator.pointer-deref.loops.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.loops.spec.ts\",\"tests\":[{\"name\":\"in for loop statements\",\"code\":[\"for i=*var, *other do *val = 42\"]},{\"name\":\"in foreach loop statements\",\"code\":[\"foreach val, *thing, key do *val = 42\"]},{\"name\":\"in while loop statements\",\"code\":[\"while *var do *val = 42\"]},{\"name\":\"in repeat loop statements\",\"code\":[\"repeat *val = 42 until *var\"]}]}","operator.pointer-deref.if.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.if.spec.ts\",\"tests\":[{\"name\":\"in if-then-else\",\"code\":[\"if *val then *var = 42 else *var = 84\"]}]}","operator.pointer-deref.case.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.case.spec.ts\",\"tests\":[{\"name\":\"all parts of case statement\",\"code\":[\"compile_opt idl2\",\"case *val of\",\" *thing: *other = 42\",\" else: *value = 84\",\"endcase\",\"end\"]}]}","operator.pointer-deref.routines.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.routines.spec.ts\",\"tests\":[{\"name\":\"in functions\",\"code\":[\"a = func(*val, *other, kw=*last)\"]},{\"name\":\"in function methods\",\"code\":[\"a = var.func(*val, *other, kw=*last)\"]},{\"name\":\"in procedure definitions\",\"code\":[\"function mypro\",\" compile_opt idl2\",\" *val = 5\",\" *val2 = 5\",\" return, !null\",\"end\"]},{\"name\":\"in procedures\",\"code\":[\"mypro, *val, *other, kw=*last\"]},{\"name\":\"in procedure methods\",\"code\":[\"var.mypro, *val, *other, kw=*last\"]},{\"name\":\"in multi-line procedures\",\"code\":[\"mypro,$\",\" *val\",\"end\"]},{\"name\":\"in procedure definitions\",\"code\":[\"pro mypro\",\"compile_opt idl2\",\" *val = 5\",\" *val2 = 5\",\" return\",\"end\"]}]}","operator.pointer-deref.paren.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.paren.spec.ts\",\"tests\":[{\"name\":\"as first statement in paren\",\"code\":[\"a = (*var)\"]}]}","operator.pointer-deref.struct.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.struct.spec.ts\",\"tests\":[{\"name\":\"after structure properties\",\"code\":[\"a = {prop: *ptr}\"]},{\"name\":\"after indexed structure properties\",\"code\":[\"a = var.(*thing)\"]}]}","operator.pointer-deref.switch.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.switch.spec.ts\",\"tests\":[{\"name\":\"all parts of switch statement\",\"code\":[\"\",\"compile_opt idl2\",\"switch *val of\",\" *thing: *other = 42\",\" *thing2: *other = 42\",\" else: *value = 84\",\"endcase\",\"end\"]}]}","operator.pointer-deref.ternary.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.ternary.spec.ts\",\"tests\":[{\"name\":\"all parts of ternary operators\",\"code\":[\"a = *val ? *truthy : *falsy\"]}]}","operator.indexing.array.spec.ts":"{\"suiteName\":\"Correctly identify array indexing\",\"fileName\":\"operator.indexing.array.spec.ts\",\"tests\":[{\"name\":\"all parts of ternary operators\",\"code\":[\"compile_opt idl2\",\"subsel = sel[*, 1:*val]\",\"end\"]}]}","operator.pointer-deref.regression.spec.ts":"{\"suiteName\":\"Correctly identify array indexing\",\"fileName\":\"operator.pointer-deref.regression.spec.ts\",\"tests\":[{\"name\":\"instead of de-referencing\",\"code\":[\"compile_opt idl2\",\"temp = reform(mask[i*8 : min([s[1] - 1, i*8 + 7]), j])\",\"end\"]}]}","strings.spec.ts":"{\"suiteName\":\"Correctly merge strings together\",\"fileName\":\"strings.spec.ts\",\"tests\":[{\"name\":\"merge single quotes\",\"code\":[\"a = 'string''escaped'\"]},{\"name\":\"merge double quotes\",\"code\":[\"a = \\\"string\\\"\\\"escaped\\\"\"]},{\"name\":\"ignore single quotes that cannot be merged\",\"code\":[\"a = 'string' 'escaped'\"]},{\"name\":\"ignore double quotes that cannot be merged\",\"code\":[\"a = \\\"string\\\" \\\"escaped\\\"\"]}]}","var-not-function.spec.ts":"{\"suiteName\":\"Correctly identify variables instead of function calls\",\"fileName\":\"var-not-function.spec.ts\",\"tests\":[{\"name\":\"for simple case\",\"code\":[\";+ my var\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt strictarr\",\"code\":[\"compile_opt strictarr\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl2\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl3\",\"code\":[\"compile_opt idl3\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]}]}"},"auto-syntax-validator-tests":{"bad-routine-def.spec.ts":"{\"suiteName\":\"Verify that we can parse and report problems\",\"fileName\":\"bad-routine-def.spec.ts\",\"tests\":[{\"name\":\"for bad function\",\"code\":[\"function \",\"\",\"; pro test_myurl\",\"\",\"a = curl_easy_init()\",\"curlopt_header = 42\",\"print, 'curl_easy_setopt', curl_easy_setopt(a, curlopt_header, 1)\",\"curlopt_url = 10002\",\"print, 'curl_easy_setopt', curl_easy_setopt(a, curlopt_url, 'http://www.google.com')\",\"print, 'curl_easy_perform', curl_easy_perform(a)\",\"curl_easy_cleanup, a\",\"end\"]},{\"name\":\"for bad pro\",\"code\":[\"pro \",\"\",\"; pro test_myurl\",\"\",\"a = curl_easy_init()\",\"curlopt_header = 42\",\"print, 'curl_easy_setopt', curl_easy_setopt(a, curlopt_header, 1)\",\"curlopt_url = 10002\",\"print, 'curl_easy_setopt', curl_easy_setopt(a, curlopt_url, 'http://www.google.com')\",\"print, 'curl_easy_perform', curl_easy_perform(a)\",\"curl_easy_cleanup, a\",\"end\"]}]}","code.0.not-closed.spec.ts":"{\"suiteName\":\"Detects problems with statements not being closed\",\"fileName\":\"code.0.not-closed.spec.ts\",\"tests\":[{\"name\":\"parentheses\",\"code\":\"(\"},{\"name\":\"brackets\",\"code\":\"[\"},{\"name\":\"structures\",\"code\":\"{\"},{\"name\":\"functions\",\"code\":\"myfunc(\"},{\"name\":\"blocks\",\"code\":\"begin\"},{\"name\":\"switch\",\"code\":\"switch\"},{\"name\":\"case\",\"code\":\"case\"},{\"name\":\"procedures\",\"code\":\"pro mypro\"},{\"name\":\"functions\",\"code\":\"function myfunc\"},{\"name\":\"across line boundaries\",\"code\":[\"( $\",\" ;something\"]},{\"name\":\"only report last instance of unclosed in main\",\"code\":[\"compile_opt idl2\",\"p = plot(var var, $\",\" plot(var var\",\"end\"]},{\"name\":\"only report last instance of unclosed in routine\",\"code\":[\"pro myAwesomePro\",\"compile_opt idl2\",\"p = plot(var var, $\",\" plot(var var\",\"end\"]}]}","code.1.unexpected-closer.spec.ts":"{\"suiteName\":\"Detects unexpected closers\",\"fileName\":\"code.1.unexpected-closer.spec.ts\",\"tests\":[{\"name\":\"finds all unexpected closers\",\"code\":[\")\",\"]\",\"}\",\"endif\",\"endelse\",\"endfor\",\"endforeach\",\"endrep\",\"endwhile\",\"endswitch\",\"endcase\",\"end\"]},{\"name\":\"correctly processes routines and expects no errors\",\"code\":[\"Function f1\",\" if keyword_set(fclip) then begin\",\" return, 1\",\" endif\",\"end\"]}]}","code.3.after-main.spec.ts":"{\"suiteName\":\"Detects problems after main level\",\"fileName\":\"code.3.after-main.spec.ts\",\"tests\":[{\"name\":\"statements after main level\",\"code\":[\"compile_opt idl2\",\"end\",\"a = 5\"]},{\"name\":\"allow comments after main\",\"code\":[\"compile_opt idl2\",\"end\",\"; ok\"]}]}","code.6.todo.spec.ts":"{\"suiteName\":\"Detects TODO statements\",\"fileName\":\"code.6.todo.spec.ts\",\"tests\":[{\"name\":\"with basic lower-case comment\",\"code\":\"; todo: something\"},{\"name\":\"with basic upper-case comment\",\"code\":\"; todo: something\"}]}","code.7.unknown-token.spec.ts":"{\"suiteName\":\"Detects unknown tokens\",\"fileName\":\"code.7.unknown-token.spec.ts\",\"tests\":[{\"name\":\"with example in structure\",\"code\":\"a = {1+2}\"},{\"name\":\"after line continuation\",\"code\":[\"compile_opt idl2\",\"a = $ , $ ; ok\",\"42\",\"end\"]},{\"name\":\"ternary without assignment\",\"code\":\"!true ? a : b\"},{\"name\":\"comma in assignment\",\"code\":\"a = ,\"},{\"name\":\"quotes in structures 1\",\"code\":\"a = {'bad'}\"},{\"name\":\"quotes in structures 2\",\"code\":\"a = {\\\"bad\\\"}\"}]}","code.8.illegal-arrow.spec.ts":"{\"suiteName\":\"Detects illegal arrows\",\"fileName\":\"code.8.illegal-arrow.spec.ts\",\"tests\":[{\"name\":\"missing super/method\",\"code\":[\"compile_opt idl2\",\"a = b-> $\",\"method\",\"end\"]},{\"name\":\"missing method with super before\",\"code\":[\"compile_opt idl2\",\"oContainer = self->IDLitContainer:: $\",\"method\",\"end\"]}]}","code.9.illegal-comma.spec.ts":"{\"suiteName\":\"Detects illegal commas\",\"fileName\":\"code.9.illegal-comma.spec.ts\",\"tests\":[{\"name\":\"after assignment\",\"code\":\"a = ,\"},{\"name\":\"standalone\",\"code\":\",\"},{\"name\":\"in right place\",\"code\":[\"a = something()\",\",\"]},{\"name\":\"in parentheses\",\"code\":[\"a = (,)\"]},{\"name\":\"in switch\",\"code\":[\"compile_opt idl2\",\"switch a, of\",\" , !true: , \",\"endswitch\",\"end\"]},{\"name\":\"in case\",\"code\":[\"compile_opt idl2\",\"case a, of\",\" , !true: , \",\"endcase\",\"end\"]},{\"name\":\"in ternary\",\"code\":[\"a = !true ? ,'bad' : ,'still bad'\"]}]}","code.10.illegal-colon.spec.ts":"{\"suiteName\":\"Detects illegal colon\",\"fileName\":\"code.10.illegal-colon.spec.ts\",\"tests\":[{\"name\":\"standalone\",\"code\":\":\"},{\"name\":\"with reserved word in jump statement\",\"code\":\"break:\"},{\"name\":\"function call\",\"code\":\"myfunc(a:b)\"},{\"name\":\"bad array syntax\",\"code\":\"myarr(a:b)\"},{\"name\":\"ignore lambda functions\",\"code\":\"a = lambda(x:x+2)\"}]}","code.11.illegal-include.spec.ts":"{\"suiteName\":\"Detects illegal include statements\",\"fileName\":\"code.11.illegal-include.spec.ts\",\"tests\":[{\"name\":\"correctly find no problems\",\"code\":\"@includeme\"},{\"name\":\"don't find in functions\",\"code\":\"a = myfunc(@bad)\"},{\"name\":\"don't find in expressions\",\"code\":\"a = @include_wrong + @way_bad\"}]}","code.12.reserved-var.spec.ts":"{\"suiteName\":\"Detects reserved variable names. Not all are detected as you might think and require other syntax rules to verify\",\"fileName\":\"code.12.reserved-var.spec.ts\",\"tests\":[{\"name\":\"correctly detects \\\"for\\\"\",\"code\":\"a = for\"},{\"name\":\"correctly detects \\\"foreach\\\"\",\"code\":\"a = foreach\"},{\"name\":\"correctly detects \\\"while\\\"\",\"code\":\"a = while\"},{\"name\":\"correctly detects \\\"do\\\"\",\"code\":\"a = do\"},{\"name\":\"correctly detects \\\"repeat\\\"\",\"code\":\"a = repeat\"},{\"name\":\"correctly detects \\\"until\\\"\",\"code\":\"a = until\"},{\"name\":\"correctly detects \\\"if\\\"\",\"code\":\"a = if\"},{\"name\":\"correctly detects \\\"then\\\"\",\"code\":\"a = then\"},{\"name\":\"correctly detects \\\"else\\\"\",\"code\":\"a = else\"},{\"name\":\"correctly detects \\\"switch\\\"\",\"code\":\"a = switch\"},{\"name\":\"correctly detects \\\"case\\\"\",\"code\":\"a = case\"},{\"name\":\"correctly detects \\\"of\\\"\",\"code\":\"a = of\"},{\"name\":\"correctly detects \\\"begin\\\"\",\"code\":\"a = begin\"},{\"name\":\"correctly detects \\\"end\\\"\",\"code\":\"a = end\"},{\"name\":\"correctly detects \\\"endif\\\"\",\"code\":\"a = endif\"},{\"name\":\"correctly detects \\\"endelse\\\"\",\"code\":\"a = endelse\"},{\"name\":\"correctly detects \\\"endfor\\\"\",\"code\":\"a = endfor\"},{\"name\":\"correctly detects \\\"endforeach\\\"\",\"code\":\"a = endforeach\"},{\"name\":\"correctly detects \\\"endrep\\\"\",\"code\":\"a = endrep\"},{\"name\":\"correctly detects \\\"endwhile\\\"\",\"code\":\"a = endwhile\"},{\"name\":\"correctly detects \\\"endswitch\\\"\",\"code\":\"a = endswitch\"},{\"name\":\"correctly detects \\\"endcase\\\"\",\"code\":\"a = endcase\"},{\"name\":\"correctly detects \\\"pro\\\"\",\"code\":\"a = pro\"},{\"name\":\"correctly detects \\\"function\\\"\",\"code\":\"a = function\"},{\"name\":\"correctly detects \\\"break\\\"\",\"code\":\"a = break\"},{\"name\":\"correctly detects \\\"continue\\\"\",\"code\":\"a = continue\"},{\"name\":\"correctly detects \\\"common\\\"\",\"code\":\"a = common\"},{\"name\":\"correctly detects \\\"compile_opt\\\"\",\"code\":\"a = compile_opt\"},{\"name\":\"correctly detects \\\"forward_function\\\"\",\"code\":\"a = forward_function\"},{\"name\":\"correctly detects \\\"goto\\\"\",\"code\":\"a = goto\"},{\"name\":\"correctly detects \\\"mod\\\"\",\"code\":\"a = mod\"},{\"name\":\"correctly detects \\\"not\\\"\",\"code\":\"a = not\"},{\"name\":\"correctly detects \\\"eq\\\"\",\"code\":\"a = eq\"},{\"name\":\"correctly detects \\\"ne\\\"\",\"code\":\"a = ne\"},{\"name\":\"correctly detects \\\"le\\\"\",\"code\":\"a = le\"},{\"name\":\"correctly detects \\\"lt\\\"\",\"code\":\"a = lt\"},{\"name\":\"correctly detects \\\"ge\\\"\",\"code\":\"a = ge\"},{\"name\":\"correctly detects \\\"gt\\\"\",\"code\":\"a = gt\"},{\"name\":\"correctly detects \\\"and\\\"\",\"code\":\"a = and\"},{\"name\":\"correctly detects \\\"or\\\"\",\"code\":\"a = or\"},{\"name\":\"correctly detects \\\"xor\\\"\",\"code\":\"a = xor\"},{\"name\":\"correctly detects \\\"inherits\\\"\",\"code\":\"a = inherits\"}]}","code.13.illegal-ternary.spec.ts":"{\"suiteName\":\"Detects illegal ternary operators\",\"fileName\":\"code.13.illegal-ternary.spec.ts\",\"tests\":[{\"name\":\"correctly find no problems\",\"code\":\"a = !true ? 'yes' : 'no'\"},{\"name\":\"find problem\",\"code\":\"!true ? 'yes' : 'no'\"}]}","code.14.colon-in-func.spec.ts":"{\"suiteName\":\"Detects illegal colons in functions\",\"fileName\":\"code.14.colon-in-func.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a = var(0:-1)\"}]}","code.15.colon-in-func-method.spec.ts":"{\"suiteName\":\"Detects illegal colons in function methods\",\"fileName\":\"code.15.colon-in-func-method.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a = objOrStruct.var(0:-1)\"}]}","code.16.double-token.spec.ts":"{\"suiteName\":\"Detects two tokens next to each other\",\"fileName\":\"code.16.double-token.spec.ts\",\"tests\":[{\"name\":\"variables\",\"code\":\"procedure, var1 var2\"},{\"name\":\"functions\",\"code\":\"func1() func2()\"},{\"name\":\"operators\",\"code\":\"a + + b\"},{\"name\":\"commas\",\"code\":\"mypro,,\"},{\"name\":\"valid structures\",\"code\":\"a = {mystruct, {known:val}}\"},{\"name\":\"bad structures\",\"code\":\"a = {{known:val}}\"},{\"name\":\"ignore comments\",\"code\":[\"; first\",\";second\"]},{\"name\":\"OK separate lines\",\"code\":[\"pro1\",\"pro2\"]},{\"name\":\"All of these operators can be next to each other\",\"code\":[\"compile_opt idl2\",\"a = b && ~c && d\",\"a = b || ~c || d\",\"a = b not ~c not d\",\"a = b eq ~c eq d\",\"a = b ne ~c ne d\",\"a = b le ~c le d\",\"a = b lt ~c lt d\",\"a = b ge ~c gt d\",\"a = b gt ~c gt d\",\"a = b and ~c and d\",\"a = b or ~c or d\",\"a = b xor ~c xor d\",\"a = b.prop.prop.prop\",\"a = 42 & b = 42 & c = 42\",\"tol = (N_ELEMENTS(tolIn) eq 1) ? tolIn[0] : use_double ? 2d-12 : 1e-5\",\"end\"]},{\"name\":\"ignore template escape characters\",\"code\":[\"a = `\\\\r\\\\r\\\\n\\\\n`\"]},{\"name\":\"ignore nested function methods (caught elsewhere)\",\"code\":[\"a = var.myfunc().ohNotOk()\"]}]}","code.16.double-token.exclusions1.spec.ts":"{\"suiteName\":\"Allows these tokens next to each other\",\"fileName\":\"code.16.double-token.exclusions1.spec.ts\",\"tests\":[{\"name\":\"string literal expressions\",\"code\":\"a = `${42}${42}`\"}]}","code.17.illegal-struct.spec.ts":"{\"suiteName\":\"Detects illegal colons in function methods\",\"fileName\":\"code.17.illegal-struct.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a ={{}}\"}]}","code.18.illegal-paren.spec.ts":"{\"suiteName\":\"Detects illegal colons in function methods\",\"fileName\":\"code.18.illegal-paren.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a = {()}\"}]}","code.19.illegal-bracket.spec.ts":"{\"suiteName\":\"Detects illegal colons in function methods\",\"fileName\":\"code.19.illegal-bracket.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a = {[]}\"}]}","code.20.return-vals-pro.spec.ts":"{\"suiteName\":\"Detects invalid return statements in procedures\",\"fileName\":\"code.20.return-vals-pro.spec.ts\",\"tests\":[{\"name\":\"ok in procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"ok in main\",\"code\":[\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return,\",\"end\"]},{\"name\":\"bad in objects\",\"code\":[\"pro mypro::method\",\" compile_opt idl2\",\" return,\",\"end\"]},{\"name\":\"bad in main\",\"code\":[\" compile_opt idl2\",\" return,\",\"end\"]},{\"name\":\"ok with comment after return\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return ; done\",\"end\"]}]}","code.21.return-vals-func.spec.ts":"{\"suiteName\":\"Detects invalid return statements in functions (too many vals)\",\"fileName\":\"code.21.return-vals-func.spec.ts\",\"tests\":[{\"name\":\"ok\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1,2\",\"end\"]},{\"name\":\"bad in objects\",\"code\":[\"function myfunc::method\",\" compile_opt idl2\",\" return,1,2\",\"end\"]},{\"name\":\"return value from function OK\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,weirdCall(1,2,3)\",\"end\"]},{\"name\":\"ok with comment after return\",\"code\":[\"function mypro\",\" compile_opt idl2\",\" return, 1 ; done\",\"end\"]}]}","code.22.return-vals-missing-func.spec.ts":"{\"suiteName\":\"Detects invalid return statements in functions (no val)\",\"fileName\":\"code.22.return-vals-missing-func.spec.ts\",\"tests\":[{\"name\":\"ok\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad in objects\",\"code\":[\"function myfunc::method\",\" compile_opt idl2\",\" return\",\"end\"]}]}","code.29.reserved-pro.spec.ts":"{\"suiteName\":\"Detects reserved procedures\",\"fileName\":\"code.29.reserved-pro.spec.ts\",\"tests\":[{\"name\":\"ok procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro WRITEU\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.30.reserved-func.spec.ts":"{\"suiteName\":\"Detects reserved functions\",\"fileName\":\"code.30.reserved-func.spec.ts\",\"tests\":[{\"name\":\"ok function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad function\",\"code\":[\"function label_region\",\" compile_opt idl2\",\" return,1\",\"end\"]}]}","code.31.return-missing.spec.ts":"{\"suiteName\":\"Detects missing return procedure in functions\",\"fileName\":\"code.31.return-missing.spec.ts\",\"tests\":[{\"name\":\"ok function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"ok in methods\",\"code\":[\"function myfunc::method\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad in methods\",\"code\":[\"function myfunc::method\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.32.routines-first.spec.ts":"{\"suiteName\":\"Detects invalid tokens before routine definition\",\"fileName\":\"code.32.routines-first.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\"@include\",\"\",\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\"]},{\"name\":\"all the problems\",\"code\":[\"; this is OK\",\"this = wrong * 5\",\"\",\"; this is OK too\",\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"; main level\",\"something = 42\",\"end\"]}]}","code.33.unclosed-main.spec.ts":"{\"suiteName\":\"Detects missing end to main level program\",\"fileName\":\"code.33.unclosed-main.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\"]},{\"name\":\"all the problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\"]},{\"name\":\"problems after end\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\",\"a = 17\"]}]}","code.33.unclosed-main.notebooks.spec.ts":"{\"suiteName\":\"Detects missing end to main level program\",\"fileName\":\"code.33.unclosed-main.notebooks.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"no problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\"],\"config\":{\"isNotebook\":true}},{\"name\":\"no problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"a = myfunc()\"],\"config\":{\"isNotebook\":true}}]}","code.34.empty-main.spec.ts":"{\"suiteName\":\"Detects empty main level programs\",\"fileName\":\"code.34.empty-main.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\"; main level\",\"compile_opt idl2\",\"something = 42\",\"end\"]},{\"name\":\"all the problems\",\"code\":[\"; main level\",\"end\"]},{\"name\":\"also problems\",\"code\":[\"\",\"end\"]}]}","code.35.after-continuation.spec.ts":"{\"suiteName\":\"Detects invalid text after line continuations\",\"fileName\":\"code.35.after-continuation.spec.ts\",\"tests\":[{\"name\":\"no problems with nothing after continuation\",\"code\":[\"compile_opt idl2\",\"something = $\",\" 5\",\"end\"]},{\"name\":\"no problems with comment\",\"code\":[\"compile_opt idl2\",\"something = $ ; ok\",\" 5\",\"end\"]},{\"name\":\"problems\",\"code\":[\"compile_opt idl2\",\"something = $ bad\",\" 5\",\"end\"]},{\"name\":\"problems, same location as previous test\",\"code\":[\"compile_opt idl2\",\"something = $ bad ; ok\",\" 5\",\"end\"]}]}","code.36.reserved-pro-method.spec.ts":"{\"suiteName\":\"Detects reserved procedure methods\",\"fileName\":\"code.36.reserved-pro-method.spec.ts\",\"tests\":[{\"name\":\"ok procedure method\",\"code\":[\"pro IDLffVideoRead::myownmethod\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad procedure method\",\"code\":[\"pro IDLffVideoRead::Cleanup\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.37.reserved-func-method.spec.ts":"{\"suiteName\":\"Detects reserved function methods\",\"fileName\":\"code.37.reserved-func-method.spec.ts\",\"tests\":[{\"name\":\"ok function method\",\"code\":[\"function list::myownmethod\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad function method\",\"code\":[\"function list::where\",\" compile_opt idl2\",\" return,1\",\"end\"]}]}","code.38.no-comp-opt.spec.ts":"{\"suiteName\":\"Detects missing compile options\",\"fileName\":\"code.38.no-comp-opt.spec.ts\",\"tests\":[{\"name\":\"ok function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" return,1\",\"end\"]},{\"name\":\"ok procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" return\",\"end\"]},{\"name\":\"ok main\",\"code\":[\"compile_opt idl2\",\"; main level program\",\" a = 5\",\"end\"]},{\"name\":\"bad main\",\"code\":[\"; main level program\",\" a = 5\",\"end\"]}]}","code.38.no-comp-opt.notebooks.spec.ts":"{\"suiteName\":\"Detects missing compile options\",\"fileName\":\"code.38.no-comp-opt.notebooks.spec.ts\",\"tests\":[{\"name\":\"ok function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" return,1\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"ok procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" return\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"ok main\",\"code\":[\"compile_opt idl2\",\"; main level program\",\" a = 5\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"bad main\",\"code\":[\"; main level program\",\" a = 5\",\"end\"],\"config\":{\"isNotebook\":true}}]}","code.39.no-idl2.spec.ts":"{\"suiteName\":\"Detects missing compile option idl2\",\"fileName\":\"code.39.no-idl2.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt hidden\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt hidden\",\" return\",\"end\"]},{\"name\":\"don't complain about idl3\",\"code\":[\"pro mypro\",\" compile_opt idl3\",\" return\",\"end\"]}]}","code.40.illegal-comp-opt.spec.ts":"{\"suiteName\":\"Detects missing compile options\",\"fileName\":\"code.40.illegal-comp-opt.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt idl2, bad1\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2, bad2\",\" return\",\"end\"]}]}","code.41.empty-comp-opt.spec.ts":"{\"suiteName\":\"Detects compile opt without options\",\"fileName\":\"code.41.empty-comp-opt.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt\",\" return\",\"end\"]}]}","code.42.use-idl2.spec.ts":"{\"suiteName\":\"Detects compile opt without options\",\"fileName\":\"code.42.use-idl2.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt defint32, strictarr\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt defint32, strictarr\",\" return\",\"end\"]}]}","code.43.expected-comma.spec.ts":"{\"suiteName\":\"Detects statements that do expect a comma first\",\"fileName\":\"code.43.expected-comma.spec.ts\",\"tests\":[{\"name\":\"in go to\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" goto jumper\",\"end\"]},{\"name\":\"in procedure method call\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" p = plot(/TEST)\",\" p.method abc\",\"end\"]},{\"name\":\"in procedure call\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" print something\",\"end\"]},{\"name\":\"in routine name\",\"code\":[\"pro mypro var1\",\" compile_opt idl2\",\"end\"]}]}","code.44.unexpected-comma.spec.ts":"{\"suiteName\":\"Detects statements that don't expect a comma first\",\"fileName\":\"code.44.unexpected-comma.spec.ts\",\"tests\":[{\"name\":\"verify braces are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" a = b[,]\",\"end\"]},{\"name\":\"verify compile_opt is caught\",\"code\":[\"pro mypro\",\" compile_opt, idl2\",\"end\"]},{\"name\":\"verify common blocks are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" common, named\",\"end\"]},{\"name\":\"verify forward function is caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" forward_function, funcy\",\"end\"]},{\"name\":\"verify function calls are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" a = func(,)\",\"end\"]},{\"name\":\"verify function method calls are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" a = b.func(,)\",\"end\"]},{\"name\":\"verify for loops are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" for, i=0,100 do print, i\",\"end\"]},{\"name\":\"verify foreach loops are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" foreach, val, arr do print, val\",\"end\"]},{\"name\":\"verify structures are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" a = {,name}\",\"end\"]}]}","code.45.multiple-comp-opt.spec.ts":"{\"suiteName\":\"Detects multiple compile_opt statements\",\"fileName\":\"code.45.multiple-comp-opt.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad main\",\"code\":[\" compile_opt idl2\",\" compile_opt idl2\",\"end\"]}]}","code.46.unclosed-quote.spec.ts":"{\"suiteName\":\"Detects unclosed quotes\",\"fileName\":\"code.46.unclosed-quote.spec.ts\",\"tests\":[{\"name\":\"ok double quote\",\"code\":[\"a = \\\"good\\\"\"]},{\"name\":\"bad double quote\",\"code\":[\"a = \\\"bad\"]},{\"name\":\"verify exclude fancy numbers\",\"code\":[\"a = \\\"0\"]},{\"name\":\"ok single quote\",\"code\":[\"a = 'good'\"]},{\"name\":\"bad single quote\",\"code\":[\"a = 'bad\"]}]}","code.47.args-first.spec.ts":"{\"suiteName\":\"Detects bad argument definitions\",\"fileName\":\"code.47.args-first.spec.ts\",\"tests\":[{\"name\":\"ok args in routine\",\"code\":[\"pro mypro, arg1, arg2, arg3, $\",\" arg4, arg5\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"bad args in routine\",\"code\":[\"pro mypro, arg1, arg2, arg3, $\",\" arg4, arg5, KW1 = kw1, $\",\" arg6, arg7\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"ok args in routine method\",\"code\":[\"pro myclass::mymethod, arg1, arg2, arg3, $\",\" arg4, arg5\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"bad args in routine method\",\"code\":[\"pro myclass::mymethod, arg1, arg2, arg3, $\",\" arg4, arg5, KW1 = kw1, $\",\" arg6, arg7\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.48.docs-missing-arg.spec.ts":"{\"suiteName\":\"Detects args missing from docs\",\"fileName\":\"code.48.docs-missing-arg.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\";\",\"; :Params:\",\"; var1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]}]}","code.49.no-args-to-doc.spec.ts":"{\"suiteName\":\"Detects documented args when there are no args\",\"fileName\":\"code.49.no-args-to-doc.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\";\",\"; :Params:\",\"; var1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";\",\"; :Params:\",\"; var1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod\",\" compile_opt idl2\",\"end\"]}]}","code.50.docs-missing-kw.spec.ts":"{\"suiteName\":\"Detects keywords missing from docs\",\"fileName\":\"code.50.docs-missing-kw.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\";\",\"; :Keywords:\",\"; KW1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";\",\";-\",\"pro myclass::mymethod, KW1=kw1\",\" compile_opt idl2\",\"end\"]}]}","code.51.no-kws-to-doc.spec.ts":"{\"suiteName\":\"Detects documented keywords when there are no keywords\",\"fileName\":\"code.51.no-kws-to-doc.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\";\",\"; :Keywords:\",\"; KW1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";\",\"; :Keywords:\",\"; KW1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod\",\" compile_opt idl2\",\"end\"]}]}","code.52.docs-missing-return.spec.ts":"{\"suiteName\":\"Detects documented keywords when there are no keywords\",\"fileName\":\"code.52.docs-missing-return.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Returns: number\",\";-\",\"function myfunc\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";-\",\"function myfunc\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.53.docs-invalid-in-out.spec.ts":"{\"suiteName\":\"Detects when in/out is incorrect for docs\",\"fileName\":\"code.53.docs-invalid-in-out.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, type=boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: wrong, optional, type=boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]}]}","code.54.docs-invalid-require.spec.ts":"{\"suiteName\":\"Detects when required/optional is incorrect for docs\",\"fileName\":\"code.54.docs-invalid-require.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, WRONG, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]}]}","code.56.docs-invalid-private.spec.ts":"{\"suiteName\":\"Detects when private/public is incorrect for docs\",\"fileName\":\"code.56.docs-invalid-private.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, hidden\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]}]}","code.57.docs-too-few-params.spec.ts":"{\"suiteName\":\"Detects when not enough documentation parameters are present\",\"fileName\":\"code.57.docs-too-few-params.spec.ts\",\"tests\":[{\"name\":\"no problems for args\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem for args\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"no problems for keywords\",\"code\":[\";+\",\"; :Keywords:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, VAR1=var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem for keywords\",\"code\":[\";+\",\"; :Keywords:\",\"; var1: in, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, VAR1=var1\",\" compile_opt idl2\",\"end\"]}]}","code.58.docs-too-many-params.spec.ts":"{\"suiteName\":\"Detects when too many documentation parameters are present\",\"fileName\":\"code.58.docs-too-many-params.spec.ts\",\"tests\":[{\"name\":\"no problems for args\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem for args\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, private, mcScrooge\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"no problems for keywords\",\"code\":[\";+\",\"; :Keywords:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, VAR1=var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem for keywords\",\"code\":[\";+\",\"; :Keywords:\",\"; var1: in, optional, boolean, public, somethingWrong\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, VAR1=var1\",\" compile_opt idl2\",\"end\"]}]}","code.59.docs-left-align.spec.ts":"{\"suiteName\":\"Detects when docs are not left-aligned as expected\",\"fileName\":\"code.59.docs-left-align.spec.ts\",\"tests\":[{\"name\":\"no problems in params/keywords\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\"; And another line\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in params/keywords\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\"; And another line\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in other blocks\",\"code\":[\";+\",\"; First line is great\",\"; THEN CHAOS ENSUES\",\";\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"no problems in variables\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+\",\" ; Some things are really awesome\",\" ; and need a big description\",\" ;-\",\" a = 42\",\"end\"]},{\"name\":\"problems in variables\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+\",\" ; Some things are really awesome\",\" ;and need a big description\",\" ;-\",\" a = 42\",\"end\"]}]}","code.60.docs-return-has-no-type.spec.ts":"{\"suiteName\":\"Detects when the returns tag for docs is missing the data type\",\"fileName\":\"code.60.docs-return-has-no-type.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns:\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.61.docs-return-invalid.spec.ts":"{\"suiteName\":\"Detects when the returns tag has too much information\",\"fileName\":\"code.61.docs-return-invalid.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\"; Fun fact about zach\",\"; he is a vegetarian\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"no problem with extra spaces\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\";\",\";\",\";\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.62.docs-return-not-needed.spec.ts":"{\"suiteName\":\"Detects when the returns tag is present for procedures\",\"fileName\":\"code.62.docs-return-not-needed.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\";-\",\"pro myroutine, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\";-\",\"pro myroutine, var1\",\" compile_opt idl2\",\"end\"]}]}","code.63.docs-not-real-param.spec.ts":"{\"suiteName\":\"Detects when a documented parameter does not exist in routine definition\",\"fileName\":\"code.63.docs-not-real-param.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem with args and keywords\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, var2, KW1=kw1, KW2=kw2\",\" compile_opt idl2\",\"end\"]},{\"name\":\"do not mistake colons in the description as parameters\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing: something else\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag: something else\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"detect in structures\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: any\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]}]}","code.64.pdocs-param-missing.spec.ts":"{\"suiteName\":\"Detects when a defined parameter is missing from user docs\",\"fileName\":\"code.64.pdocs-param-missing.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem with args and keywords\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\";\",\"; :Keywords:\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\"end\"]}]}","code.65.string-literal-too-many-args.spec.ts":"{\"suiteName\":\"Detects when a string literal has too many arguments\",\"fileName\":\"code.65.string-literal-too-many-args.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":\"`${1.234,\\\"%10.3f\\\"}`\"},{\"name\":\"no problems - string literal in formatting\",\"code\":\"`${1.234,`%${w}.3f`}`\"},{\"name\":\"problem with too many args\",\"code\":\"`${1.234,abc,\\\"%10.3f\\\"}`\"}]}","code.66.bad-continue.spec.ts":"{\"suiteName\":\"Detects bad continue statements\",\"fileName\":\"code.66.bad-continue.spec.ts\",\"tests\":[{\"name\":\"no problems in loops\",\"code\":[\"compile_opt idl2\",\"for i=0,10 do if !true then continue\",\"foreach val, key do if !true then continue\",\"while !true do if !false then continue\",\"repeat if !true then continue until !true\",\"end\"]},{\"name\":\"problems outside of loops\",\"code\":[\"compile_opt idl2\",\"continue\",\"end\"]}]}","code.67.bad-break.spec.ts":"{\"suiteName\":\"Detects bad break statements\",\"fileName\":\"code.67.bad-break.spec.ts\",\"tests\":[{\"name\":\"no problems in loops\",\"code\":[\"compile_opt idl2\",\"for i=0,10 do if !true then break\",\"foreach val, key do if !true then break\",\"while !true do if !false then break\",\"repeat if !true then break until !true\",\"end\"]},{\"name\":\"no problems in switch\",\"code\":[\"compile_opt idl2\",\"switch a of\",\" !true: break\",\"endswitch\",\"end\"]},{\"name\":\"no problems in case\",\"code\":[\"compile_opt idl2\",\"case a of\",\" !true: break\",\"endcase\",\"end\"]},{\"name\":\"problems outside of loops\",\"code\":[\"compile_opt idl2\",\"break\",\"end\"]}]}","code.68.expected-statement.spec.ts":"{\"suiteName\":\"Detects tokens that are empty but shouldn't be\",\"fileName\":\"code.68.expected-statement.spec.ts\",\"tests\":[{\"name\":\"problem in assignment\",\"code\":[\"compile_opt idl2\",\"a = \",\"end\"]},{\"name\":\"problem in basic operators\",\"code\":[\"compile_opt idl2\",\"a = 42 +\",\"end\"]},{\"name\":\"problem in compound operator\",\"code\":[\"compile_opt idl2\",\"a *= \",\"end\"]},{\"name\":\"problem in logical operator\",\"code\":[\"compile_opt idl2\",\"a = 5 and \",\"end\"]},{\"name\":\"problem in negative sign\",\"code\":[\"compile_opt idl2\",\"a = - \",\"end\"]},{\"name\":\"problem in pointer dereference\",\"code\":[\"compile_opt idl2\",\"a = *\",\"end\"]},{\"name\":\"problem in parentheses\",\"code\":[\"compile_opt idl2\",\"a = ()\",\"end\"]},{\"name\":\"problem in for\",\"code\":[\"compile_opt idl2\",\"for\",\"end\"]},{\"name\":\"problem in foreach\",\"code\":[\"compile_opt idl2\",\"foreach\",\"end\"]},{\"name\":\"problem in foreach\",\"code\":[\"compile_opt idl2\",\"while\",\"end\"]},{\"name\":\"problem in foreach\",\"code\":[\"compile_opt idl2\",\"for i=0,1 do\",\"end\"]},{\"name\":\"problem in repeat\",\"code\":[\"compile_opt idl2\",\"repeat\",\"end\"]},{\"name\":\"problem in until\",\"code\":[\"compile_opt idl2\",\"repeat a = 5 until\",\"end\"]},{\"name\":\"problem in if\",\"code\":[\"compile_opt idl2\",\"if\",\"end\"]},{\"name\":\"problem in then\",\"code\":[\"compile_opt idl2\",\"if !true then\",\"end\"]},{\"name\":\"problem in else\",\"code\":[\"compile_opt idl2\",\"if !true then a = 42 else\",\"end\"]},{\"name\":\"problem in ternary then\",\"code\":[\"compile_opt idl2\",\"a = !true ?\",\"end\"]},{\"name\":\"problem in ternary else\",\"code\":[\"compile_opt idl2\",\"a = !true ? 42 :\",\"end\"]},{\"name\":\"problem in switch\",\"code\":[\"compile_opt idl2\",\"switch\",\"end\"]},{\"name\":\"problem in case\",\"code\":[\"compile_opt idl2\",\"case\",\"end\"]},{\"name\":\"problem in of for switch\",\"code\":[\"compile_opt idl2\",\"switch !true of\",\"end\"]},{\"name\":\"problem in of for case\",\"code\":[\"compile_opt idl2\",\"switch !true of\",\"end\"]}]}","code.69.unfinished-dot.spec.ts":"{\"suiteName\":\"Detects tokens that are empty but shouldn't be\",\"fileName\":\"code.69.unfinished-dot.spec.ts\",\"tests\":[{\"name\":\"as procedure-method or property access, but incomplete\",\"code\":[\"compile_opt idl2\",\"a.\",\"end\"]},{\"name\":\"as function method or property access, but incomplete\",\"code\":[\"compile_opt idl2\",\"a = b.\",\"end\"]},{\"name\":\"standalone 1\",\"code\":[\"compile_opt idl2\",\"a = .\",\"end\"]},{\"name\":\"standalone 2\",\"code\":[\"compile_opt idl2\",\".\",\"end\"]}]}","code.70.illegal-hex-escape.spec.ts":"{\"suiteName\":\"Verify string literal escape characters\",\"fileName\":\"code.70.illegal-hex-escape.spec.ts\",\"tests\":[{\"name\":\"only have a problem with the last one\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"end\"]}]}","code.71.unknown-template-escape.spec.ts":"{\"suiteName\":\"Find unknown string literal escape characters\",\"fileName\":\"code.71.unknown-template-escape.spec.ts\",\"tests\":[{\"name\":\"no problems with all good\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00`\",\"end\"]},{\"name\":\"problems with incomplete and bad ones\",\"code\":[\"compile_opt idl2\",\"a = `\\\\ `\",\"a = `\\\\a`\",\"a = `\\\\42`\",\"a = `\\\\lark \\\\r\\\\n`\",\"end\"]}]}","code.72.duplicate-arg-kw-var-def.spec.ts":"{\"suiteName\":\"Find duplicate arg and keyword variables and detect\",\"fileName\":\"code.72.duplicate-arg-kw-var-def.spec.ts\",\"tests\":[{\"name\":\"no problems when OK\",\"code\":[\"pro mypro, a, b, AKW = akw, BKW = bkw\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in procedures\",\"code\":[\"pro mypro, a, a, b, B = b, C = b\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in procedure methods\",\"code\":[\"pro myclass::mymethod, a, a, b, B = b, C = b\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in functions\",\"code\":[\"function myfunc, a, a, b, B = b, C = b\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problems in function methods\",\"code\":[\"function myclass::mymethod, a, a, b, B = b, C = b\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.73.duplicate-kw-def.spec.ts":"{\"suiteName\":\"Find duplicate keyword definitions\",\"fileName\":\"code.73.duplicate-kw-def.spec.ts\",\"tests\":[{\"name\":\"no problems when OK\",\"code\":[\"pro mypro, AKW = akw, BKW = bkw\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in procedures\",\"code\":[\"pro mypro, AKW = akw, AKW = bkw\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in procedure methods\",\"code\":[\"pro myclass::mypro, AKW = akw, AKW = bkw\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in functions\",\"code\":[\"function myfunc, AKW = akw, AKW = bkw\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problems in function methods\",\"code\":[\"function myfunc::mymethod, AKW = akw, AKW = bkw\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.74.duplicate-property.spec.ts":"{\"suiteName\":\"Find duplicate properties and find\",\"fileName\":\"code.74.duplicate-property.spec.ts\",\"tests\":[{\"name\":\"no problems when OK\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a = {a:a, B :b}\",\"end\"]},{\"name\":\"problems when we have them\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a = {a:a, A :b}\",\"end\"]}]}","code.75.duplicate-kw-usage.spec.ts":"{\"suiteName\":\"Find keyword usage and detect problems in\",\"fileName\":\"code.75.duplicate-kw-usage.spec.ts\",\"tests\":[{\"name\":\"procedures\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"plot, kw1=5, KW1=5, kw1=5, /KW1\",\"end\"]},{\"name\":\"procedure methods\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a.plot, kw1=5, KW1=5, kw1=5, /KW1\",\"end\"]},{\"name\":\"functions\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a = plot(kw1=5, KW1=5, kw1=5, /KW1)\",\"end\"]},{\"name\":\"function methods\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a = b.plot(kw1=5, KW1=5, kw1=5, /KW1)\",\"end\"]}]}","code.76.init-method-pro.spec.ts":"{\"suiteName\":\"Check for init methods\",\"fileName\":\"code.76.init-method-pro.spec.ts\",\"tests\":[{\"name\":\"being procedures incorrectly\",\"code\":[\"pro mypro::init\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.77.unknown-structure.spec.ts":"{\"suiteName\":\"Check for structure names\",\"fileName\":\"code.77.unknown-structure.spec.ts\",\"tests\":[{\"name\":\"reported not in class definitions\",\"code\":[\"pro auto_doc_example\",\" compile_opt idl2\",\" a = {ENVIRaster2}\",\"end\"]},{\"name\":\"ignored in class definitions\",\"code\":[\"pro auto_doc_example__define\",\" compile_opt idl2\",\" a = {ENVIRaster2}\",\"end\"]}]}","code.78.illegal-chain.spec.ts":"{\"suiteName\":\"Check for bad access\",\"fileName\":\"code.78.illegal-chain.spec.ts\",\"tests\":[{\"name\":\"from function calls\",\"code\":[\"pro so_bad\",\" compile_opt idl2\",\" a = myfunc().ohNo\",\" a = myfunc().(42)\",\" myfunc().ohMeOhMy\",\" a = myfunc().ohNotOk()\",\"end\"]},{\"name\":\"from function method calls\",\"code\":[\"pro so_sad\",\" compile_opt idl2\",\" a = var.myfunc().ohNo\",\" a = var.myfunc().(42)\",\" var.myfunc().ohMeOhMy\",\" a = var.myfunc().ohNotOk()\",\"end\"]}]}","code.79.docs-missing-struct.spec.ts":"{\"suiteName\":\"Check for missing structure definitions\",\"fileName\":\"code.79.docs-missing-struct.spec.ts\",\"tests\":[{\"name\":\"from docs 1\",\"code\":[\";+\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]},{\"name\":\"from docs 2\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: any\",\"; Placeholder docs for argument or keyword\",\"; prop2:any\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]},{\"name\":\"ignore when no docs\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]},{\"name\":\"ignore when just procedure\",\"code\":[\";+\",\";-\",\"pro pro4\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]},{\"name\":\"ignore when function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" return, 1\",\"end\"]}]}","code.80.docs-missing-prop.spec.ts":"{\"suiteName\":\"Check for missing properties\",\"fileName\":\"code.80.docs-missing-prop.spec.ts\",\"tests\":[{\"name\":\"in our docs\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: any\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]}]}","code.81.class-no-params.spec.ts":"{\"suiteName\":\"Check for args and keywords in procedure class definitions\",\"fileName\":\"code.81.class-no-params.spec.ts\",\"tests\":[{\"name\":\"with arg\",\"code\":[\"pro pro4__define, a\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"with kw\",\"code\":[\"pro pro4__define, KW = kw\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"with both\",\"code\":[\"pro pro4__define, arg, KW = kw\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"ok with neither\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.82.docs-prop-too-few-params.spec.ts":"{\"suiteName\":\"Not enough parameters for properties\",\"fileName\":\"code.82.docs-prop-too-few-params.spec.ts\",\"tests\":[{\"name\":\"without anything\",\"code\":[\";+\",\"; :NYStruct0:\",\"; prop1:\",\"; Placeholder docs for argument, keyword, or property\",\";\",\"; :NYStruct:\",\"; prop2: \",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3__define\",\" compile_opt idl3\",\"\",\" !null = {NYStruct0, prop1: 5}\",\"\",\" !null = {NYStruct, inherits NYStruct0, prop2: 6}\",\"end\"]},{\"name\":\"no problems\",\"code\":[\";+\",\"; :NYStruct0:\",\"; prop1: any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\"; :NYStruct:\",\"; prop2: String | number\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3__define\",\" compile_opt idl3\",\"\",\" !null = {NYStruct0, prop1: 5}\",\"\",\" !null = {NYStruct, inherits NYStruct0, prop2: 6}\",\"end\"]}]}","code.83.docs-prop-too-many-params.spec.ts":"{\"suiteName\":\"Too many parameters for properties\",\"fileName\":\"code.83.docs-prop-too-many-params.spec.ts\",\"tests\":[{\"name\":\"with extra\",\"code\":[\";+\",\"; :NYStruct0:\",\"; prop1: any, bad\",\"; Placeholder docs for argument, keyword, or property\",\";\",\"; :NYStruct:\",\"; prop2: String, noop\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3__define\",\" compile_opt idl3\",\"\",\" !null = {NYStruct0, prop1: 5}\",\"\",\" !null = {NYStruct, inherits NYStruct0, prop2: 6}\",\"end\"]},{\"name\":\"no problems\",\"code\":[\";+\",\"; :NYStruct0:\",\"; prop1: Hash\",\"; Placeholder docs for argument, keyword, or property\",\";\",\"; :NYStruct:\",\"; prop2: String\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3__define\",\" compile_opt idl3\",\"\",\" !null = {NYStruct0, prop1: 5}\",\"\",\" !null = {NYStruct, inherits NYStruct0, prop2: 6}\",\"end\"]}]}","code.84.illegal-subscript.spec.ts":"{\"suiteName\":\"Illegal subscript\",\"fileName\":\"code.84.illegal-subscript.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Dictionary\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro index_problems, arg1, arg2, arg3, arg4, arg5\",\" compile_opt idl3\",\"\",\" ; for arrays\",\" a1 = arg1[*]\",\" a2 = arg1[0, 1, *]\",\" a3 = arg1[0, 1, 2]\",\" a4 = arg1[0 : -1 : 1]\",\" a5 = arg1[0, 1, *]\",\"\",\" ; for lists\",\" l1 = arg2[*]\",\" l2 = arg2[0, 1, *]\",\" l3 = arg2[0, 1, 2]\",\" l4 = arg2[0 : -1 : 1]\",\" l5 = arg2[0, 1, *]\",\"\",\" ; for hashes\",\" h1 = arg3[*]\",\" h2 = arg3[0, 1, *]\",\" h3 = arg3[0, 1, 2]\",\" h4 = arg3[0 : -1 : 1]\",\" h5 = arg3[0, 1, *]\",\"\",\" ; for ordered hashes\",\" oh1 = arg4[*]\",\" oh2 = arg4[0, 1, *]\",\" oh3 = arg4[0, 1, 2]\",\" oh4 = arg4[0 : -1 : 1]\",\" oh5 = arg4[0, 1, *]\",\"\",\" ; for dictionaries\",\" d1 = arg5[*]\",\" d2 = arg5[0, 1, *]\",\" d3 = arg5[0, 1, 2]\",\" d3 = arg5[0 : -1 : 1]\",\" d5 = arg5[0, 1, *]\",\"end\"]}]}","code.85.illegal-struct-op.spec.ts":"{\"suiteName\":\"Illegal structure\",\"fileName\":\"code.85.illegal-struct-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro struct_checks\",\"compile_opt idl2\",\"\",\"str = {a: 42}\",\"\",\"a = 1 + str\",\"\",\"b = str + {a: 42}\",\"\",\"c = str + list()\",\"\",\"d = str + hash()\",\"\",\"e = str + orderedhash()\",\"\",\"f = str + dictionary()\",\"end\"]}]}","code.86.illegal-list-op.spec.ts":"{\"suiteName\":\"Illegal list\",\"fileName\":\"code.86.illegal-list-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro list_checks\",\"compile_opt idl2\",\"\",\"a = 1 + list()\",\"\",\"b = list() + list()\",\"\",\"c = list() + hash()\",\"\",\"d = list() + orderedhash()\",\"\",\"e = list() + dictionary()\",\"end\"]}]}","code.87.illegal-hash-op.spec.ts":"{\"suiteName\":\"Illegal hash\",\"fileName\":\"code.87.illegal-hash-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro hash_checks\",\"compile_opt idl2\",\"\",\"a = 1 + hash()\",\"\",\"b = hash() + list()\",\"\",\"c = hash() + hash()\",\"\",\"d = hash() + orderedhash()\",\"\",\"e = hash() + dictionary()\",\"end\"]}]}","code.88.illegal-ordered-hash-op.spec.ts":"{\"suiteName\":\"Illegal ordered hash\",\"fileName\":\"code.88.illegal-ordered-hash-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro orderedhash_checks\",\"compile_opt idl2\",\"\",\"a = 1 + orderedhash()\",\"\",\"b = orderedhash() + list()\",\"\",\"c = orderedhash() + hash()\",\"\",\"d = orderedhash() + orderedhash()\",\"\",\"e = orderedhash() + dictionary()\",\"end\"]}]}","code.89.illegal-dictionary-op.spec.ts":"{\"suiteName\":\"Illegal dictionary\",\"fileName\":\"code.89.illegal-dictionary-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro dictionary_checks\",\"compile_opt idl2\",\"\",\"a = 1 + dictionary()\",\"\",\"b = dictionary() + list()\",\"\",\"c = dictionary() + hash()\",\"\",\"d = dictionary() + orderedhash()\",\"\",\"e = dictionary() + dictionary()\",\"end\"]}]}","code.90.potential-type-incompatibility.spec.ts":"{\"suiteName\":\"Potential type incompatibility in\",\"fileName\":\"code.90.potential-type-incompatibility.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro incompatible_checks\",\"compile_opt idl2\",\"\",\"a = 1 + ENVIRaster()\",\"\",\"b = 1 + plot()\",\"end\"]},{\"name\":\"no problems with array creation\",\"code\":[\"pro incompatible_checks\",\"compile_opt idl2\",\"\",\"arr1 = [ENVIRaster(), ENVIMetaspectralRaster(), ENVISubsetRaster()]\",\"arr2 = [{}, {}]\",\"end\"]},{\"name\":\"problems with array creation\",\"code\":[\"pro incompatible_checks\",\"compile_opt idl2\",\"\",\"bad1 = [ENVIRaster(), {}]\",\"bad2 = [{}, 1]\",\"end\"]}]}","code.91.illegal-index-type.spec.ts":"{\"suiteName\":\"Illegal index checks for\",\"fileName\":\"code.91.illegal-index-type.spec.ts\",\"tests\":[{\"name\":\"all types\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Dictionary\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro index_problems, arg1, arg2, arg3, arg4, arg5\",\" compile_opt idl3\",\"\",\" ; for arrays\",\" !null = arg1[plot()]\",\" !null = arg1[1j]\",\" !null = arg1[1i]\",\" !null = arg1[1di]\",\" !null = arg1[1dj]\",\"\",\" ; for lists\",\" !null = arg2[plot()]\",\" !null = arg2[1j]\",\" !null = arg2[1i]\",\" !null = arg2[1di]\",\" !null = arg2[1dj]\",\"\",\" ; for hashes\",\" !null = arg3[plot()]\",\" !null = arg3[1j]\",\" !null = arg3[1i]\",\" !null = arg3[1di]\",\" !null = arg3[1dj]\",\"\",\" ; for ordered hashes\",\" !null = arg4[plot()]\",\" !null = arg4[1j]\",\" !null = arg4[1i]\",\" !null = arg4[1di]\",\" !null = arg4[1dj]\",\"\",\" ; for dictionaries\",\" !null = arg5[plot()]\",\" !null = arg5[1j]\",\" !null = arg5[1i]\",\" !null = arg5[1di]\",\" !null = arg5[1dj]\",\"end\"]},{\"name\":\"allow boolean since it is really a number\",\"code\":[\"pro index_problems\",\" compile_opt idl2\",\"\",\" ; for arrays\",\" display = strarr(c)\",\" i = keyword_set(!null)\",\" !null = display[i]\",\"end\"]}]}","code.92.potential-arr-type-incompatibility.spec.ts":"{\"suiteName\":\"Array data type incompatibility\",\"fileName\":\"code.92.potential-arr-type-incompatibility.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro array_incompatibility, arg1, arg4, arg5\",\" compile_opt idl2\",\"\",\" ; OK\",\" a = arg1 + arg4\",\"\",\" ; bad\",\" b = arg1 + arg4 + arg5\",\"end\"]}]}","code.93.ptr-nothing-to-de-ref.spec.ts":"{\"suiteName\":\"De-referencing noting\",\"fileName\":\"code.93.ptr-nothing-to-de-ref.spec.ts\",\"tests\":[{\"name\":\"with asterisks\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\"\",\" ; yikes\",\" a = *\",\"\",\" ; bad\",\" b = (*)\",\"end\"]}]}","code.94.ptr-de-ref-illegal.spec.ts":"{\"suiteName\":\"Pointer de-ref without pointers\",\"fileName\":\"code.94.ptr-de-ref-illegal.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Pointer | String\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, Pointer | Pointer\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pointers, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; number\",\" a = *arg1\",\"\",\" ; enviraster\",\" b = *arg3[0]\",\"\",\" ; any, unable to de-reference\",\" d = *5\",\"\",\" ; any\",\" f = *arg5\",\"\",\" ; union of type args\",\" g = *arg6\",\"end\"]}]}","code.95.indexing-error.spec.ts":"{\"suiteName\":\"Errors for indexing\",\"fileName\":\"code.95.indexing-error.spec.ts\",\"tests\":[{\"name\":\"variables that cannot be indexed\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Arguments:\",\"; a: in, required, Number\",\"; Placeholder docs for argument, keyword, or property\",\"; b: in, required, ComplexNumber\",\"; Placeholder docs for argument, keyword, or property\",\"; c: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; d: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\"; e: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; f: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\"; g: in, required, Dictionary\",\"; Placeholder docs for argument, keyword, or property\",\"; h: in, required, ENVIRasterMetadata\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function allowed_to_index, a, b, c, d, e, f, g, h\",\" compile_opt idl2\",\"\",\" ; OK\",\" !null = c[0]\",\" !null = d[0]\",\" !null = e[0]\",\" !null = f[0]\",\" !null = g[0]\",\"\",\" ; also OK, though non standard IDL types\",\" !null = h[0]\",\"\",\" ; problems\",\" byte = ('s' + 1b)[0]\",\" int = ('s' + 1s)[0]\",\" uint = ('s' + 1us)[0]\",\" long = ('s' + 1l)[0]\",\" ulong = ('s' + 1ul)[0]\",\" long64 = ('s' + 1ll)[0]\",\" ulong64 = ('s' + 1ull)[0]\",\" float1 = ('s' + 1.)[0]\",\" float2 = ('s' + 1e)[0]\",\" double = ('s' + 1d)[0]\",\" biginteger = ('s' + BigInteger(5))[0]\",\" number = ('s' + a)[0]\",\" complexfloat = ('s' + 1.i)[0]\",\" complexdouble = ('s' + 1di)[0]\",\" complexdouble = ('s' + 1dj)[0]\",\" complexnumber1 = ('s' + a + 1di + 1dj)[0]\",\" complexnumber2 = (a + b)[0]\",\"\",\" return, 1\",\"end\"]}]}","code.96.ptr-de-ref-ambiguity.spec.ts":"{\"suiteName\":\"Pointer de-ref without pointers\",\"fileName\":\"code.96.ptr-de-ref-ambiguity.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Pointer | String\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, Pointer | Pointer\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pointers, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; number\",\" a = *arg1\",\"\",\" ; enviraster\",\" b = *arg3[0]\",\"\",\" ; ambiguous\",\" c = *arg4\",\"\",\" ; any\",\" f = *arg5\",\"\",\" ; union of type args\",\" g = *arg6\",\"end\"]}]}","code.97.unknown-kw.spec.ts":"{\"suiteName\":\"Check for known keywords\",\"fileName\":\"code.97.unknown-kw.spec.ts\",\"tests\":[{\"name\":\"and report errors if we dont have \\\"_extra\\\" or \\\"_ref_extra\\\"\",\"code\":[\";+\",\"; :Description:\",\"; Constructor\",\";\",\"; :Returns:\",\"; myclass\",\";\",\";-\",\"function myclass::Init\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw: out, optional, Array\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myclass::method, kw = kw, _ref_extra = _extra\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw: out, optional, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro myclass::method, kw = kw, _extra = _extra\",\" compile_opt idl2\",\"end\",\"\",\";+\",\"; :Description:\",\"; Class definition procedure\",\";\",\";-\",\"pro myclass__define\",\" compile_opt idl2\",\"\",\" struct = {myclass}\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw: out, optional, Long\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myfunc, kw = kw\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw: out, optional, Byte\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro mypro, kw = kw\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main level program\",\"compile_opt idl2\",\"\",\"; procedures\",\"mypro, kw = a, /kw2, kw3 = 3\",\"\",\"; functions\",\"!null = myfunc(kw = b, /kw2, kw3 = 3)\",\"\",\"; make class for methods\",\"var = myclass()\",\"\",\"; procedure methods\",\"var.method, kw = c, /kw2, kw3 = 3\",\"\",\"; function methods\",\"!null = var.method(kw = d, /kw2, kw3 = 3)\",\"end\"]}]}","code.97.unknown-kw.exceptions.spec.ts":"{\"suiteName\":\"Check for known keywords\",\"fileName\":\"code.97.unknown-kw.exceptions.spec.ts\",\"tests\":[{\"name\":\"and exclude these cases\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"\",\"; procedures\",\"p = plot(/tes)\",\"end\"]},{\"name\":\"unless we have extra or ref extra (only one at a time)\",\"code\":[\";+\",\"; :Keywords:\",\"; _ref_extra: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro auto_doc_example2, _ref_extra = ex\",\" compile_opt idl2\",\"\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; _extra: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro auto_doc_example, _extra = ex\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main\",\"compile_opt idl2\",\"\",\"; OK with only extra\",\"auto_doc_example, /anything_i_want\",\"\",\"; OK with only ref extra\",\"auto_doc_example2, /anything_i_want\",\"\",\"end\"]}]}","code.97.unknown-kw.exceptions2.spec.ts":"{\"suiteName\":\"Check for known keywords\",\"fileName\":\"code.97.unknown-kw.exceptions2.spec.ts\",\"tests\":[{\"name\":\"but always ignore extra and strict extra\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function auto_doc_example\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main\",\"compile_opt idl2\",\"\",\"; no error\",\"a = auto_doc_example(_extra = !null)\",\"\",\"; no error\",\"a = auto_doc_example(_strict_extra = !null)\",\"\",\"end\"]}]}","code.97.unknown-kw.exceptions3.spec.ts":"{\"suiteName\":\"Check for known keywords\",\"fileName\":\"code.97.unknown-kw.exceptions3.spec.ts\",\"tests\":[{\"name\":\"but always obj_new\",\"code\":[\"; main\",\"compile_opt idl2\",\"\",\"; no error\",\"outClass = 'something'\",\"!null = OBJ_NEW(outClass, FOLD_CASE=!null))\",\"\",\"end\"]}]}","code.98.incomplete-ternary.spec.ts":"{\"suiteName\":\"Check for incomplete ternary\",\"fileName\":\"code.98.incomplete-ternary.spec.ts\",\"tests\":[{\"name\":\"operators missing the second half\",\"code\":[\"compile_opt idl2\",\"; wrong\",\"a = !true ? 5\",\"\",\"; right\",\"!null = !true ? 5 : 'yeah'\",\"\",\"; right\",\"!null = !true ? (5) : 'yeah'\",\"\",\"end\"]}]}","code.99.undefined-var.spec.ts":"{\"suiteName\":\"Detect undefined variables\",\"fileName\":\"code.99.undefined-var.spec.ts\",\"tests\":[{\"name\":\"in most places\",\"code\":[\";+\",\"; :Arguments:\",\"; a: in, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\"; b: out, required, Long\",\"; Placeholder docs for argument, keyword, or property\",\"; c: out, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro undefined_without_common, a, b, c\",\" compile_opt idl2\",\"\",\" ; direct vars\",\" test1 = bad\",\"\",\" ; within child branches\",\" test2 = (ok = 5) + wrong\",\"\",\" ; as keyword\",\" test3 = ENVIRaster(metadata = meta) ; formatting matches docs\",\"\",\" ; OK\",\" for i = 0, 100 do begin\",\" !null = i\",\" endfor\",\"\",\" ; item is bad\",\" foreach val, item, key do begin\",\" !null = val\",\" !null = key\",\" endforeach\",\"\",\" ; noBueno is bad\",\" noBueno->method\",\"end\"]},{\"name\":\"never define self\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function dataToMemoryRaster\",\" compile_opt idl2\",\"\",\" ; should error\",\" self = 5\",\"\",\" ; should error\",\" a = self\",\"\",\" return, 1\",\"end\"]},{\"name\":\"define self in methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::mymethod\",\" compile_opt idl2\",\"\",\" ; no error\",\" self = 5\",\"\",\" ; no error\",\" a = self\",\"\",\" return, 1\",\"end\"]},{\"name\":\"catc\",\"code\":[\"compile_opt idl2\",\"filename = filepath('qb_boulder_msi', root = nv.root_dir)\",\"end\"]}]}","code.99.undefined-var.edge-cases.spec.ts":"{\"suiteName\":\"Check unknown variables in edge cases\",\"fileName\":\"code.99.undefined-var.edge-cases.spec.ts\",\"tests\":[{\"name\":\"in keywords\",\"code\":[\"compile_opt idl2\",\"filename = filepath('qb_boulder_msi', root = nv.root_dir)\",\"end\"]},{\"name\":\"pointer value assignment\",\"code\":[\"compile_opt idl2\",\"*other = 42\",\"end\"]}]}","code.99.undefined-var.exceptions1.spec.ts":"{\"suiteName\":\"Don't check unknown keywords\",\"fileName\":\"code.99.undefined-var.exceptions1.spec.ts\",\"tests\":[{\"name\":\"in in methods that we dont know\",\"code\":[\" compile_opt idl2\",\"l = luna(/in_package)\",\"(l.expects(routine)).toRunFunction, raster, _output = output\",\"end\"]},{\"name\":\"verify we process parents before children\",\"code\":[\" compile_opt idl2\",\" item = list()\",\" ; item is bad\",\" foreach val, item, key do begin\",\" val = 5\",\" endforeach\",\"end\"]}]}","code.99.undefined-var.exceptions2.spec.ts":"{\"suiteName\":\"Without docs, keywords are least restrictive\",\"fileName\":\"code.99.undefined-var.exceptions2.spec.ts\",\"tests\":[{\"name\":\"and bidirectional\",\"code\":[\"pro unknown_kw_relaxed, kw = kw\",\"compile_opt idl2\",\"end\",\"\",\"; main\",\"compile_opt idl2\",\"unknown_kw_relaxed, kw = newVar\",\"end\"]}]}","code.99.undefined-var.exceptions3.spec.ts":"{\"suiteName\":\"Without known global, arguments are least restrictive\",\"fileName\":\"code.99.undefined-var.exceptions3.spec.ts\",\"tests\":[{\"name\":\"and bidirectional\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Arguments:\",\"; data: bidirectional, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function dataToMemoryRaster, data\",\" compile_opt idl2, hidden\",\"\",\" ; make everything\",\" oSvc = obj_new('IDLcfSvcOpenMemoryRaster') ; IDLcfSvcOpenMemoryRaster()\",\" ok = oSvc.Open(memory_data = data, '', oRaster, data_type = data.typecode)\",\" ok = IDLcfGetServiceObject(!null, 'ManageRaster', oManageRaster)\",\" void = oManageRaster.ManageBands(oRaster)\",\"\",\" ; return our raster\",\" return, ENVIWrapComponent(oRaster)\",\"end\"]}]}","code.99.undefined-var.exceptions4.spec.ts":"{\"suiteName\":\"Keyword variables should be defined\",\"fileName\":\"code.99.undefined-var.exceptions4.spec.ts\",\"tests\":[{\"name\":\"and not report errors\",\"code\":[\"function bridge_it::Init, nbridges, init = init, msg = msg, logdir = logdir, nrefresh = nrefresh, prefix = prefix\",\"compile_opt idl2, hidden\",\"\",\"; check to see if different messag eneeds to be used\",\"if ~keyword_set(msg) then self.msg = 'Time to complete bridge process (sec): ' else self.msg = msg\",\"\",\"; check to see if we have a number of processes to complete before refreshing the bridges\",\"; otherwise set the refresh number to an absurbly high result!\",\"if keyword_set(nrefresh) then self.nrefresh = nrefresh else self.nrefresh = 1000000l\",\"\",\"; check if init keyword is set, if so then we want to save the init string\",\"if keyword_set(init) then self.init = strjoin(init, ' & ')\",\"\",\"; check if logdir is specified\",\"if keyword_set(logdir) then begin\",\" if file_test(logdir) then begin\",\" self.logdir = logdir\",\" endif else begin\",\" message, 'Specified LOGDIR does not exist!'\",\" endelse\",\"endif\",\"\",\"return, 1\",\"end\"]}]}","code.99.undefined-var.exceptions5.spec.ts":"{\"suiteName\":\"With lambda functions\",\"fileName\":\"code.99.undefined-var.exceptions5.spec.ts\",\"tests\":[{\"name\":\"do not extract or check variables\",\"code\":[\"; main level\",\"compile_opt idl2\",\"!null = lambda(n:n le 3 || min(n mod [2:fix(sqrt(n))]))\",\"end\"]}]}","code.99.undefined-var.exceptions6.spec.ts":"{\"suiteName\":\"With common blocks\",\"fileName\":\"code.99.undefined-var.exceptions6.spec.ts\",\"tests\":[{\"name\":\"skip the name of the common block\",\"code\":[\"; main level\",\"compile_opt idl2\",\"common theName, a1, bb, cc\",\"end\"]}]}","code.100.potential-undefined-var.spec.ts":"{\"suiteName\":\"Detect undefined variables\",\"fileName\":\"code.100.potential-undefined-var.spec.ts\",\"tests\":[{\"name\":\"when we have a common block present\",\"code\":[\";+\",\"; :Arguments:\",\"; a: in, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\"; b: out, required, Long\",\"; Placeholder docs for argument, keyword, or property\",\"; c: out, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro undefined_with_common, a, b, c\",\" compile_opt idl2\",\" common\",\"\",\" ; direct vars\",\" test1 = bad\",\"\",\" ; within child branches\",\" test2 = (ok = 5) + wrong\",\"\",\" ; as keyword\",\" test3 = ENVIRaster(metadata = meta) ; formatting matches docs\",\"\",\" ; OK\",\" for i = 0, 100 do begin\",\" !null = i\",\" endfor\",\"\",\" ; item is bad\",\" foreach val, item, key do begin\",\" !null = val\",\" !null = key\",\" endforeach\",\"\",\" ; noBueno is bad\",\" noBueno->method\",\"end\"]},{\"name\":\"dont add a var for the first child of a common block\",\"code\":[\"pro color_edit_back\",\"compile_opt idl2\",\"\",\"common color_edit, wxsize, wysize, r0\",\"\",\"for i = wysize - 60, wysize - 30 do tv, ramp, wxsize / 2 - 256, i\",\"\",\"cx = wxsize / 4.\",\"cy = wysize - 90. - r0\",\"\",\"a = color_edit\",\"\",\"return\",\"end\"]}]}","code.101.var-use-before-def.spec.ts":"{\"suiteName\":\"Use variable before it is defined\",\"fileName\":\"code.101.var-use-before-def.spec.ts\",\"tests\":[{\"name\":\"when we dont have a common-block present\",\"code\":[\"pro before_defined_no_common\",\"compile_opt idl2\",\"\",\"; problemo\",\"a = b\",\"\",\"; define\",\"b = 5\",\"\",\"; complex problem0\",\"c = d + (d = 5)\",\"\",\"; no problemo\",\"f = (g = 6) + g\",\"end\"]}]}","code.101.var-use-before-def.exceptions.spec.ts":"{\"suiteName\":\"Use variable before it is defined\",\"fileName\":\"code.101.var-use-before-def.exceptions.spec.ts\",\"tests\":[{\"name\":\"does not trigger anywhere\",\"code\":[\"function ReadExif::_GetName, tag, image = img, photo = pht, gps = gps, iop = iop\",\"compile_opt idl2, hidden\",\"\",\"name = ''\",\"img = keyword_set(img)\",\"pht = keyword_set(pht)\",\"gps = keyword_set(gps)\",\"iop = keyword_set(iop)\",\"\",\"; if none are set, default to all\",\"if (array_equal([img, pht, gps, iop], 0)) then begin\",\" img = (pht = (gps = (iop = 1)))\",\"endif\",\"\",\"if (iop) then begin\",\" if (self.ioptags.HasKey(tag)) then begin\",\" name = self.ioptags[tag]\",\" endif\",\"endif\",\"\",\"if (gps) then begin\",\" if (self.gpstags.HasKey(tag)) then begin\",\" name = self.gpstags[tag]\",\" endif\",\"endif\",\"\",\"if (pht) then begin\",\" if (self.phototags.HasKey(tag)) then begin\",\" name = self.phototags[tag]\",\" endif\",\"endif\",\"\",\"if (img) then begin\",\" if (self.imagetags.HasKey(tag)) then begin\",\" name = self.imagetags[tag]\",\" endif\",\"endif\",\"\",\"return, name\",\"end\"]}]}","code.102.potential-var-use-before-def.spec.ts":"{\"suiteName\":\"Use variable before it is defined\",\"fileName\":\"code.102.potential-var-use-before-def.spec.ts\",\"tests\":[{\"name\":\"when we dont have a common-block present\",\"code\":[\"pro before_defined_common\",\"compile_opt idl2\",\"common\",\"\",\"; problemo\",\"a = b\",\"\",\"; define\",\"b = 5\",\"\",\"; complex problem0\",\"c = d + (d = 5)\",\"\",\"; no problemo\",\"f = (g = 6) + g\",\"end\"]}]}","code.102.potential-var-use-before-def.exception.spec.ts":"{\"suiteName\":\"Use variable before it is defined\",\"fileName\":\"code.102.potential-var-use-before-def.exception.spec.ts\",\"tests\":[{\"name\":\"does not get triggered here\",\"code\":[\"pro IDLitVisAxis2::OnViewportChange, oDestination\",\" compile_opt idl2, hidden\",\"\",\" if (obj_valid(oDestination)) then $\",\" oDestination.GetProperty, current_zoom = zoomFactor $\",\" else $\",\" zoomFactor = 1.0\",\"\",\"end\"]}]}","code.103.ambiguous-keyword-abbreviation.spec.ts":"{\"suiteName\":\"Keywords that are abbreviated but\",\"fileName\":\"code.103.ambiguous-keyword-abbreviation.spec.ts\",\"tests\":[{\"name\":\"have multiple for auto complete\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw1: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\"; kw2: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myclass::mymethod, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw1: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\"; kw2: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro myclass::mymethod, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2\",\"\",\"end\",\"\",\";+\",\"; :myclass:\",\";-\",\"pro myclass__define\",\" compile_opt idl2\",\"\",\" !null = {myclass}\",\"\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw1: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\"; kw2: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function auto_doc_example, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw1: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\"; kw2: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro auto_doc_example, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main leve program\",\"compile_opt idl2\",\"\",\"; problem 1\",\"auto_doc_example, /kw\",\"\",\"; problem 2\",\"!null = auto_doc_example(kw = 5)\",\"\",\"a = {myclass}\",\"\",\"; problem 3\",\"a.mymethod, kw = 5\",\"\",\"; problem 4\",\"!null = a.mymethod(/kw)\",\"\",\"end\"]}]}","code.103.ambiguous-keyword-abbreviation.exceptions.spec.ts":"{\"suiteName\":\"Keywords that could be abbreviated\",\"fileName\":\"code.103.ambiguous-keyword-abbreviation.exceptions.spec.ts\",\"tests\":[{\"name\":\"but have a direct match\",\"code\":[\"; main leve program\",\"compile_opt idl2\",\"\",\"; problem 1\",\"device, /close\",\"\",\"end\"]}]}","code.104.unused-var.spec.ts":"{\"suiteName\":\"Unused variable\",\"fileName\":\"code.104.unused-var.spec.ts\",\"tests\":[{\"name\":\"problems with args, kws, and vars\",\"code\":[\"function test1, a, b, kw = kw\",\" compile_opt idl2\",\" c = 5\",\" return, 1\",\"end\"]},{\"name\":\"no problems when used\",\"code\":[\"function test1, a, b, kw = kw\",\" compile_opt idl2\",\" c = 5\",\" !null = a + b + c + keyword_set(kw)\",\" return, 1\",\"end\"]}]}","code.104.unused-var.exceptions1.spec.ts":"{\"suiteName\":\"Unused variable\",\"fileName\":\"code.104.unused-var.exceptions1.spec.ts\",\"tests\":[{\"name\":\"exceptions for static references\",\"code\":[\"compile_opt idl2\",\"!null = ENVI.openRaster()\",\"end\"]}]}","code.104.unused-var.exceptions2.spec.ts":"{\"suiteName\":\"Unused var exceptions when parentheses for indexing\",\"fileName\":\"code.104.unused-var.exceptions2.spec.ts\",\"tests\":[{\"name\":\"is var\",\"code\":[\";+ my var\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"is not var\",\"code\":[\"compile_opt strictarr\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"is not var\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"is not var\",\"code\":[\"compile_opt idl3\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]}]}","code.105.illegal-var-index.spec.ts":"{\"suiteName\":\"Indexing with parentheses\",\"fileName\":\"code.105.illegal-var-index.spec.ts\",\"tests\":[{\"name\":\"for simple case\",\"code\":[\";+ my var\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt strictarr\",\"code\":[\"compile_opt strictarr\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl2\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl3\",\"code\":[\"compile_opt idl3\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]}]}","type-validation-reference.spec.ts":"{\"suiteName\":\"All the places we want to make sure we test for\",\"fileName\":\"type-validation-reference.spec.ts\",\"tests\":[{\"name\":\"type validation\",\"code\":[\";+\",\"; :Arguments:\",\"; arg3: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro validate_problems, arg3, arg4\",\" compile_opt idl3\",\"\",\" ; validation edge cases\",\" ; same variables should always have validation applied, but not always saved\",\" dup1 = arg3[arg4]\",\" dup1 = arg3[arg4]\",\"\",\" ; anything with assignment before should validate\",\" !x.charsize = arg3[arg4]\",\" !null = arg3[arg4]\",\"\",\" ; arguments and keywords\",\" a = polot1(arg3[arg4], $\",\" arg3[arg4], $\",\" thing = arg3[arg4], $\",\" thang = arg3[arg4])\",\"\",\" ; left-side of the equation\",\" arg3[arg4] = 5\",\" (arg3[arg4]) = 5\",\" (myfunc(arg3[arg4])) = 5\",\" !null = (myfunc2(arg3[arg4]))\",\" !null = (myfunc3(arg3[arg4])) + 1\",\"\",\" ; arguments\",\" a = polot2(arg3[arg4], arg3[arg4])\",\"end\"]}]}"},"auto-selected-token-tests":{"basic.spec.ts":"{\"suiteName\":\"Correctly identifies search terms from syntax tree\",\"fileName\":\"basic.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"code\":[\"function myfunc\",\" return,1\",\"end\",\"\",\"; main level\",\"something = 42\",\"end\"],\"position\":[{\"line\":0,\"character\":0},{\"line\":3,\"character\":0}]}]}","keywords.spec.ts":"{\"suiteName\":\"Correctly identifies keywords from routine calls\",\"fileName\":\"keywords.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"code\":[\"; main level\",\"r = ENVIRaster(NCOLUMNS = nCols, NROWS = nrows)\",\"end\"],\"position\":[{\"line\":1,\"character\":20},{\"line\":1,\"character\":35}]}]}","proper-parent.spec.ts":"{\"suiteName\":\"Correctly identifies search terms from syntax tree\",\"fileName\":\"proper-parent.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens with multiple parent routines\",\"code\":[\"function myfunc2\",\" compile_opt idl2\",\" a = 42\",\" return,1\",\"end\",\"\",\"function myfunc1\",\" compile_opt idl2\",\" a = 17\",\" return,1\",\"end\"],\"position\":[{\"line\":2,\"character\":2},{\"line\":8,\"character\":2}]}]}","relaxed.spec.ts":"{\"suiteName\":\"Correctly use relaxed options for hover help\",\"fileName\":\"relaxed.spec.ts\",\"tests\":[{\"name\":\"at end of assignment\",\"code\":[\"function myfunc1\",\" compile_opt idl2\",\" a = \",\" return,1\",\"end\"],\"position\":[{\"line\":2,\"character\":5},{\"line\":8,\"character\":6}]}]}","within-parent.spec.ts":"{\"suiteName\":\"Find the right token when we do/don't have anything selected\",\"fileName\":\"within-parent.spec.ts\",\"tests\":[{\"name\":\"with a branch token\",\"code\":[\"args.setData, \",\"end\"],\"position\":[{\"line\":0,\"character\":12},{\"line\":0,\"character\":13},{\"line\":0,\"character\":14},{\"line\":0,\"character\":15},{\"line\":0,\"character\":16}]}]}"},"auto-hover-help-tests":{"bracket-paren.1.spec.ts":"{\"suiteName\":\"Correctly provides hover help for\",\"fileName\":\"bracket-paren.1.spec.ts\",\"tests\":[{\"name\":\"things after brackets and parentheses\",\"file\":\"idl/test/hover-help/bracket_paren.pro\",\"position\":[{\"line\":14,\"character\":20},{\"line\":17,\"character\":21},{\"line\":17,\"character\":27},{\"line\":20,\"character\":20},{\"line\":23,\"character\":25},{\"line\":24,\"character\":13}]}]}","comment-regression.spec.ts":"{\"suiteName\":\"Correctly get hover help\",\"fileName\":\"comment-regression.spec.ts\",\"tests\":[{\"name\":\"for comment edge case\",\"file\":\"idl/test/hover-help/comment_regression.pro\",\"position\":[{\"line\":3,\"character\":12},{\"line\":5,\"character\":13}]}]}","docs-overrides.spec.ts":"{\"suiteName\":\"Correctly overrides doc hover help\",\"fileName\":\"docs-overrides.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/docs_overrides.pro\",\"position\":[{\"line\":3,\"character\":8},{\"line\":3,\"character\":13},{\"line\":3,\"character\":22}]}]}","docs-overrides.2.spec.ts":"{\"suiteName\":\"Correctly overrides doc hover help\",\"fileName\":\"docs-overrides.2.spec.ts\",\"tests\":[{\"name\":\"for structure properties\",\"file\":\"idl/test/hover-help/docs_overrides2.pro\",\"position\":[{\"line\":6,\"character\":11}]}]}","ex-1.spec.ts":"{\"suiteName\":\"Correctly identifies search terms from syntax tree\",\"fileName\":\"ex-1.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/awesomerasterintersection.pro\",\"position\":[{\"line\":87,\"character\":10},{\"line\":90,\"character\":7},{\"line\":91,\"character\":25}]}]}","ex-2.spec.ts":"{\"suiteName\":\"Correctly identifies keywords from routine calls\",\"fileName\":\"ex-2.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/myfunc.pro\",\"position\":[{\"line\":24,\"character\":12},{\"line\":24,\"character\":20},{\"line\":27,\"character\":6},{\"line\":32,\"character\":6},{\"line\":40,\"character\":13}]}]}","ex-3.spec.ts":"{\"suiteName\":\"Correctly finds no information for parameters in docs but not code\",\"fileName\":\"ex-3.spec.ts\",\"tests\":[{\"name\":\"with keywords and arguments\",\"file\":\"idl/test/hover-help/only_code.pro\",\"position\":[{\"line\":26,\"character\":2},{\"line\":27,\"character\":2}]}]}","init-methods.spec.ts":"{\"suiteName\":\"Verify hover-help for\",\"fileName\":\"init-methods.spec.ts\",\"tests\":[{\"name\":\"init methods\",\"file\":\"idl/test/hover-help/init_method.pro\",\"position\":[{\"line\":13,\"character\":14},{\"line\":16,\"character\":19}]}]}","keywords.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"keywords.spec.ts\",\"tests\":[{\"name\":\"abbreviated keywords\",\"file\":\"idl/test/hover-help/keywords.pro\",\"position\":[{\"line\":4,\"character\":13}]}]}","literal-types.spec.ts":"{\"suiteName\":\"Correctly display help for literal types\",\"fileName\":\"literal-types.spec.ts\",\"tests\":[{\"name\":\"for numbers and strings\",\"file\":\"idl/test/hover-help/literal_types.pro\",\"position\":[{\"line\":1,\"character\":2},{\"line\":2,\"character\":2},{\"line\":3,\"character\":2},{\"line\":4,\"character\":2},{\"line\":5,\"character\":2}]}]}","no-end.spec.ts":"{\"suiteName\":\"Correctly does not provide hover help\",\"fileName\":\"no-end.spec.ts\",\"tests\":[{\"name\":\"for end tokens but does for the beginning\",\"file\":\"idl/test/hover-help/middle_functions.pro\",\"position\":[{\"line\":3,\"character\":6},{\"line\":3,\"character\":10}]}]}","obj-new.spec.ts":"{\"suiteName\":\"Correctly find find definition from obj new\",\"fileName\":\"obj-new.spec.ts\",\"tests\":[{\"name\":\"case 1\",\"file\":\"idl/test/hover-help/obj_new.pro\",\"position\":[{\"line\":53,\"character\":12}]},{\"name\":\"case 2\",\"file\":\"idl/test/hover-help/obj_new.pro\",\"position\":[{\"line\":56,\"character\":12}]},{\"name\":\"keywords\",\"file\":\"idl/test/hover-help/obj_new.pro\",\"position\":[{\"line\":56,\"character\":35}]}]}","structures.spec.ts":"{\"suiteName\":\"Provide hover help for\",\"fileName\":\"structures.spec.ts\",\"tests\":[{\"name\":\"anonymous structures\",\"file\":\"idl/test/hover-help/structures.pro\",\"position\":[{\"line\":8,\"character\":10},{\"line\":9,\"character\":12},{\"line\":10,\"character\":14},{\"line\":11,\"character\":12}]}]}","structures-properties.spec.ts":"{\"suiteName\":\"Provide hover help for\",\"fileName\":\"structures-properties.spec.ts\",\"tests\":[{\"name\":\"named structure properties\",\"file\":\"idl/test/hover-help/structures2.pro\",\"position\":[{\"line\":13,\"character\":24},{\"line\":13,\"character\":34}]},{\"name\":\"anonymous structure properties\",\"file\":\"idl/test/hover-help/structures2.pro\",\"position\":[{\"line\":15,\"character\":9},{\"line\":15,\"character\":25}]}]}","syntax-errors.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"syntax-errors.spec.ts\",\"tests\":[{\"name\":\"incorrect function call\",\"file\":\"idl/test/hover-help/syntax_error.pro\",\"position\":[{\"line\":1,\"character\":8}]},{\"name\":\"the end of the function call start (regression test for crash)\",\"file\":\"idl/test/hover-help/syntax_error.pro\",\"position\":[{\"line\":1,\"character\":11}]}]}","tasks.spec.ts":"{\"suiteName\":\"Task type hover help\",\"fileName\":\"tasks.spec.ts\",\"tests\":[{\"name\":\"as regression for task type parsing and serialization\",\"file\":\"idl/test/hover-help/tasks.pro\",\"position\":[{\"line\":13,\"character\":14},{\"line\":14,\"character\":14},{\"line\":15,\"character\":14}]}]}","variables.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"variables.spec.ts\",\"tests\":[{\"name\":\"system variables\",\"file\":\"idl/test/hover-help/variables.pro\",\"position\":[{\"line\":5,\"character\":2}]}]}","type-detection.methods.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"type-detection.methods.spec.ts\",\"tests\":[{\"name\":\"function method\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":10,\"character\":13}]},{\"name\":\"procedure methods\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":13,\"character\":6}]}]}","type-detection.properties.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"type-detection.properties.spec.ts\",\"tests\":[{\"name\":\"first level properties that exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":16,\"character\":16}]},{\"name\":\"secondary properties that exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":16,\"character\":23}]},{\"name\":\"first level properties that dont exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":19,\"character\":16}]},{\"name\":\"secondary properties that dont exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":22,\"character\":25}]},{\"name\":\"static properties that exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":25,\"character\":16}]},{\"name\":\"static properties that dont exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":28,\"character\":22}]}]}","type-detection.methods-inheritance.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"type-detection.methods-inheritance.spec.ts\",\"tests\":[{\"name\":\"function method\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":10,\"character\":13}]},{\"name\":\"procedure methods\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":13,\"character\":6}]}]}","type-detection.properties-inheritance.spec.ts":"{\"suiteName\":\"Correctly provide hover help for inheritance of\",\"fileName\":\"type-detection.properties-inheritance.spec.ts\",\"tests\":[{\"name\":\"first level properties that exist\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":16,\"character\":16}]},{\"name\":\"secondary properties that exist\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":16,\"character\":23}]},{\"name\":\"first level properties that dont exist\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":19,\"character\":16}]},{\"name\":\"secondary properties that dont exist\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":22,\"character\":25}]}]}","type-detection.sysvar.spec.ts":"{\"suiteName\":\"Correctly provide hover help for system variable\",\"fileName\":\"type-detection.sysvar.spec.ts\",\"tests\":[{\"name\":\"properties that exist\",\"file\":\"idl/test/hover-help/types_sysvar.pro\",\"position\":[{\"line\":3,\"character\":15}]},{\"name\":\"properties that don't exist\",\"file\":\"idl/test/hover-help/types_sysvar.pro\",\"position\":[{\"line\":4,\"character\":14}]}]}","type-detection.keywords.spec.ts":"{\"suiteName\":\"Correctly provide hover help for keywords\",\"fileName\":\"type-detection.keywords.spec.ts\",\"tests\":[{\"name\":\"in method calls\",\"file\":\"idl/test/hover-help/types_keywords.pro\",\"position\":[{\"line\":10,\"character\":27},{\"line\":12,\"character\":19},{\"line\":12,\"character\":27}]}]}"},"auto-token-definition-tests":{"functions.spec.ts":"{\"suiteName\":\"Correctly find function definitions\",\"fileName\":\"functions.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":11}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":61,\"character\":11}]}]}","function-methods.spec.ts":"{\"suiteName\":\"Correctly find definitions for function methods\",\"fileName\":\"function-methods.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":17},{\"line\":85,\"character\":14}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":88,\"character\":19}]}]}","include.spec.ts":"{\"suiteName\":\"Correctly find find include\",\"fileName\":\"include.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/include_test.pro\"],\"position\":[{\"line\":4,\"character\":7}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/include_test.pro\"],\"position\":[{\"line\":7,\"character\":8}]}]}","keywords.procedures.spec.ts":"{\"suiteName\":\"Correctly find definitions for keywords\",\"fileName\":\"keywords.procedures.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":7}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":16},{\"line\":55,\"character\":8}]},{\"name\":\"real binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":30}]},{\"name\":\"fake binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":37}]}]}","keywords.procedure-methods.spec.ts":"{\"suiteName\":\"Correctly find definitions for keywords\",\"fileName\":\"keywords.procedure-methods.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":16},{\"line\":76,\"character\":16}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":25},{\"line\":76,\"character\":25},{\"line\":79,\"character\":17}]},{\"name\":\"real binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":38},{\"line\":76,\"character\":38}]},{\"name\":\"fake binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":45},{\"line\":76,\"character\":45}]}]}","keywords.functions.spec.ts":"{\"suiteName\":\"Correctly find definitions for keywords\",\"fileName\":\"keywords.functions.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":15}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":24},{\"line\":61,\"character\":16}]},{\"name\":\"real binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":37}]},{\"name\":\"fake binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":44}]}]}","keywords.function-methods.spec.ts":"{\"suiteName\":\"Correctly find definitions for keywords\",\"fileName\":\"keywords.function-methods.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":24},{\"line\":85,\"character\":24}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":33},{\"line\":85,\"character\":33},{\"line\":88,\"character\":25}]},{\"name\":\"real binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":46},{\"line\":85,\"character\":46}]},{\"name\":\"fake binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":53},{\"line\":85,\"character\":53}]}]}","obj-new.spec.ts":"{\"suiteName\":\"Correctly find find definition from obj new\",\"fileName\":\"obj-new.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/obj_new.pro\"],\"position\":[{\"line\":53,\"character\":12}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/obj_new.pro\"],\"position\":[{\"line\":56,\"character\":12}]}]}","procedures.spec.ts":"{\"suiteName\":\"Correctly find procedure definitions\",\"fileName\":\"procedures.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":6}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":55,\"character\":2}]}]}","procedure-methods.spec.ts":"{\"suiteName\":\"Correctly find definitions for procedure methods\",\"fileName\":\"procedure-methods.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":8},{\"line\":76,\"character\":8}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":79,\"character\":6}]}]}","properties.spec.ts":"{\"suiteName\":\"Correctly find definitions for properties\",\"fileName\":\"properties.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":64,\"character\":14},{\"line\":67,\"character\":14}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":70,\"character\":14}]}]}","structures.spec.ts":"{\"suiteName\":\"Correctly find definitions in structures\",\"fileName\":\"structures.spec.ts\",\"tests\":[{\"name\":\"using structure names\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":40,\"character\":9}]},{\"name\":\"using properties (inherited, ours, fake)\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":43,\"character\":19},{\"line\":43,\"character\":31},{\"line\":43,\"character\":42}]},{\"name\":\"anonymous properties\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":94,\"character\":22}]}]}","tasks.spec.ts":"{\"suiteName\":\"Correctly find definitions for task files\",\"fileName\":\"tasks.spec.ts\",\"tests\":[{\"name\":\"from ENVITask function\",\"files\":[\"idl/test/token-def/tasks.pro\",\"idl/test/token-def/atanomalydetection.task\"],\"position\":[{\"line\":2,\"character\":12}]}]}","variables.spec.ts":"{\"suiteName\":\"Correctly find definitions in structures\",\"fileName\":\"variables.spec.ts\",\"tests\":[{\"name\":\"real variables\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":46,\"character\":9}]},{\"name\":\"fake variables\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":49,\"character\":9}]}]}"},"auto-auto-complete-tests":{"bracket-paren.1.spec.ts":"{\"suiteName\":\"Correctly provides auto complete for\",\"fileName\":\"bracket-paren.1.spec.ts\",\"tests\":[{\"name\":\"things after brackets and parentheses\",\"file\":\"idl/test/auto-complete/bracket_paren.pro\",\"position\":[{\"line\":14,\"character\":18},{\"line\":17,\"character\":24},{\"line\":20,\"character\":17},{\"line\":23,\"character\":19},{\"line\":24,\"character\":11}]}]}","dont-complete.spec.ts":"{\"suiteName\":\"Don't do auto-complete\",\"fileName\":\"dont-complete.spec.ts\",\"tests\":[{\"name\":\"for any of these\",\"file\":\"idl/test/auto-complete/dont_complete.pro\",\"position\":[{\"line\":1,\"character\":18},{\"line\":1,\"character\":19},{\"line\":1,\"character\":34},{\"line\":6,\"character\":9},{\"line\":6,\"character\":10},{\"line\":6,\"character\":25},{\"line\":13,\"character\":13},{\"line\":16,\"character\":2},{\"line\":17,\"character\":2},{\"line\":20,\"character\":9},{\"line\":21,\"character\":9},{\"line\":22,\"character\":9},{\"line\":25,\"character\":10},{\"line\":28,\"character\":10}]}]}","executive-commands.1.spec.ts":"{\"suiteName\":\"Correctly send only executive commands\",\"fileName\":\"executive-commands.1.spec.ts\",\"tests\":[{\"name\":\"when we auto-complete\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":36,\"character\":2}]}]}","include-properties.spec.ts":"{\"suiteName\":\"Include properties\",\"fileName\":\"include-properties.spec.ts\",\"tests\":[{\"name\":\"for procedure methods with only dots\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":22,\"character\":4}]},{\"name\":\"for static properties\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":26,\"character\":15}]}]}","in-structures.1.spec.ts":"{\"suiteName\":\"Verify auto-complete in structures\",\"fileName\":\"in-structures.1.spec.ts\",\"tests\":[{\"name\":\"for properties, property completion, and normal property completion\",\"file\":\"idl/test/auto-complete/in_structures.pro\",\"position\":[{\"line\":17,\"character\":15},{\"line\":19,\"character\":22},{\"line\":21,\"character\":47}]}]}","include.spec.ts":"{\"suiteName\":\"Verify auto-complete for\",\"fileName\":\"include.spec.ts\",\"tests\":[{\"name\":\"include statements\",\"file\":\"idl/test/auto-complete/include.pro\",\"position\":[{\"line\":2,\"character\":1}]}]}","init-methods.spec.ts":"{\"suiteName\":\"Verify auto-complete for\",\"fileName\":\"init-methods.spec.ts\",\"tests\":[{\"name\":\"init methods\",\"file\":\"idl/test/auto-complete/init_method.pro\",\"position\":[{\"line\":13,\"character\":10},{\"line\":16,\"character\":18}]}]}","keywords.1.spec.ts":"{\"suiteName\":\"Correctly provides auto complete for keywords\",\"fileName\":\"keywords.1.spec.ts\",\"tests\":[{\"name\":\"things after brackets and parentheses\",\"file\":\"idl/test/auto-complete/keywords.pro\",\"position\":[{\"line\":4,\"character\":10},{\"line\":7,\"character\":11},{\"line\":10,\"character\":15},{\"line\":13,\"character\":13},{\"line\":16,\"character\":14}]}]}","keywords.2.spec.ts":"{\"suiteName\":\"Correctly exclude keywords\",\"fileName\":\"keywords.2.spec.ts\",\"tests\":[{\"name\":\"for these cases\",\"file\":\"idl/test/auto-complete/keywords.pro\",\"position\":[{\"line\":22,\"character\":12},{\"line\":23,\"character\":11},{\"line\":24,\"character\":9}]}]}","methods.1.spec.ts":"{\"suiteName\":\"Verify types being used for\",\"fileName\":\"methods.1.spec.ts\",\"tests\":[{\"name\":\"methods\",\"file\":\"idl/test/auto-complete/types.pro\",\"position\":[{\"line\":10,\"character\":8},{\"line\":13,\"character\":4},{\"line\":26,\"character\":12}]}]}","no-init.spec.ts":"{\"suiteName\":\"Exclude init method\",\"fileName\":\"no-init.spec.ts\",\"tests\":[{\"name\":\"for function methods\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":7,\"character\":12}]}]}","no-paren.spec.ts":"{\"suiteName\":\"Exclude parentheses\",\"fileName\":\"no-paren.spec.ts\",\"tests\":[{\"name\":\"for functions and function methods\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":10,\"character\":9},{\"line\":11,\"character\":12},{\"line\":12,\"character\":14}]}]}","no-properties.spec.ts":"{\"suiteName\":\"Exclude properties\",\"fileName\":\"no-properties.spec.ts\",\"tests\":[{\"name\":\"for function methods\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":18,\"character\":12},{\"line\":19,\"character\":14}]},{\"name\":\"for procedure method\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":23,\"character\":7}]}]}","no-variables.spec.ts":"{\"suiteName\":\"Exclude variables\",\"fileName\":\"no-variables.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":15,\"character\":9}]}]}","procedures.1.spec.ts":"{\"suiteName\":\"When in procedure, send procedure tokens\",\"fileName\":\"procedures.1.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"file\":\"idl/test/auto-complete/procedures.pro\",\"position\":[{\"line\":4,\"character\":2}]}]}","obj-new.spec.ts":"{\"suiteName\":\"Correctly return auto-complete from obj-new\",\"fileName\":\"obj-new.spec.ts\",\"tests\":[{\"name\":\"real\",\"file\":\"idl/test/auto-complete/obj_new.pro\",\"position\":[{\"line\":53,\"character\":26}]},{\"name\":\"fake\",\"file\":\"idl/test/auto-complete/obj_new.pro\",\"position\":[{\"line\":56,\"character\":29}]}]}","procedures.spec.ts":"{\"suiteName\":\"Procedures\",\"fileName\":\"procedures.spec.ts\",\"tests\":[{\"name\":\"including user and variables\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":2,\"character\":0}]}]}","properties.1.spec.ts":"{\"suiteName\":\"Verify types being used for\",\"fileName\":\"properties.1.spec.ts\",\"tests\":[{\"name\":\"properties\",\"file\":\"idl/test/auto-complete/types.pro\",\"position\":[{\"line\":16,\"character\":15},{\"line\":19,\"character\":21},{\"line\":19,\"character\":21}]}]}","regression.1.spec.ts":"{\"suiteName\":\"Regression tests\",\"fileName\":\"regression.1.spec.ts\",\"tests\":[{\"name\":\"for problems\",\"file\":\"idl/test/auto-complete/regression1.pro\",\"position\":[{\"line\":2,\"character\":28}]}]}","structures-anonymous.spec.ts":"{\"suiteName\":\"Structures\",\"fileName\":\"structures-anonymous.spec.ts\",\"tests\":[{\"name\":\"without a name\",\"file\":\"idl/test/auto-complete/structures.pro\",\"position\":[{\"line\":8,\"character\":12},{\"line\":9,\"character\":14},{\"line\":10,\"character\":21}]},{\"name\":\"auto-complete for structure names\",\"file\":\"idl/test/auto-complete/structures.pro\",\"position\":[{\"line\":13,\"character\":11},{\"line\":14,\"character\":14}]}]}","tasks.functions.spec.ts":"{\"suiteName\":\"Task auto complete\",\"fileName\":\"tasks.functions.spec.ts\",\"tests\":[{\"name\":\"to make sure they look nice\",\"file\":\"idl/test/auto-complete/task_functions.pro\",\"position\":[{\"line\":3,\"character\":8}],\"startsWith\":\"ENVITask\"}]}","tasks.properties.spec.ts":"{\"suiteName\":\"Task auto complete\",\"fileName\":\"tasks.properties.spec.ts\",\"tests\":[{\"name\":\"as regression for task type parsing\",\"file\":\"idl/test/auto-complete/tasks.pro\",\"position\":[{\"line\":13,\"character\":4},{\"line\":14,\"character\":4},{\"line\":15,\"character\":4}]}]}","method-regression.spec.ts":"{\"suiteName\":\"Methods\",\"fileName\":\"method-regression.spec.ts\",\"tests\":[{\"name\":\"inside the paren showing variables\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":10,\"character\":10},{\"line\":11,\"character\":13},{\"line\":12,\"character\":15}]}]}","system-variables.1.spec.ts":"{\"suiteName\":\"Correctly send only system variables\",\"fileName\":\"system-variables.1.spec.ts\",\"tests\":[{\"name\":\"when we auto-complete\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":29,\"character\":3},{\"line\":30,\"character\":9}]}]}","variables.1.spec.ts":"{\"suiteName\":\"Correctly finds the right variables\",\"fileName\":\"variables.1.spec.ts\",\"tests\":[{\"name\":\"when we auto-complete\",\"file\":\"idl/test/auto-complete/variables.pro\",\"position\":[{\"line\":6,\"character\":10},{\"line\":9,\"character\":2}]}]}"},"auto-local-global-scope-compile-types-tests":{"all-docs-work-right.spec.ts":"{\"suiteName\":\"Correctly gets docs and variables\",\"fileName\":\"all-docs-work-right.spec.ts\",\"tests\":[{\"name\":\"for a routine\",\"code\":[\"\",\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\" ;+ awesome variable with docs\",\" a = 42\",\" ;+\",\" ; Big comment block here\",\" ; like a great code writer\",\" ;-\",\" b = 42\",\"end\",\"\"]}]}","common.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"common.spec.ts\",\"tests\":[{\"name\":\"common, excluding the first of the common block\",\"code\":[\"pro color_edit_back\",\"compile_opt idl2\",\"\",\"common color_edit, wxsize, wysize, r0\",\"end\"]}]}","complex-docs-example1.spec.ts":"{\"suiteName\":\"Complex real world test\",\"fileName\":\"complex-docs-example1.spec.ts\",\"tests\":[{\"name\":\"with past failure in complex docs\",\"code\":[\";h+\",\"; Copyright (c) 2018 Harris Geospatial Solutions, Inc.\",\"; \",\"; Licensed under MIT. See LICENSE.txt for additional details and information.\",\";h-\",\"\",\"\",\"\",\";+\",\"; :Description:\",\"; Tool for determining the intersection between two rasters based on their\",\"; spatial reference and spatial extent. Both rasters will also contain only\",\"; the valid pixels from each scene for analysis. In other words, if a pixel\",\"; is `off` in the first image and not the second, it will be turned `off` in\",\"; each of the output rasters for consistency. If one of the rasters does not\",\"; have a data ignore value, then a pixel state mask is automatically generated\",\"; so that you can mask the output rasters if needed.\",\"; \",\"; The pixel size of the output rasters will be the smallest x and y\",\"; pixel size from each raster.\",\";\",\";\",\";\",\"; :Examples:\",\"; ```idl\",\"; ;start ENVI\",\"; e = envi(/HEADLESS)\",\"; \",\"; ;make sure we have access to our ENVI tasks\",\"; awesomeENVIAlgorithms, /INIT\",\"; \",\"; ;specify two rasters to process\",\"; raster1 = e.openRaster(file1)\",\"; raster2 = e.openRaster(file2)\",\"; \",\"; ;get our task\",\"; task = ENVITask('AwesomeRasterIntersection')\",\"; task.INPUT_RASTER1 = raster1\",\"; task.INPUT_RASTER2 = raster2\",\"; task.execute\",\"; \",\"; ;print our output locations\",\"; print, task.OUTPUT_RASTER1_URI\",\"; print, task.OUTPUT_RASTER2_URI\",\"; ```\",\";\",\"; :Keywords:\",\"; DEBUG: in, optional, type=boolean, private\",\"; If set, errors are stopped on.\",\"; DATA_IGNORE_VALUE: in, optional, type=number\",\"; If one or both of your input rasters do not have\",\"; a data ignore value metadata item, you can specify\",\"; GENERATE_PIXEL_STATE_MASK: in, optional, type=boolean\",\"; If set, then an addititonal output raster is created\",\"; that represents which pixels can be processed or not.\",\"; \",\"; This will automatically be generated if one of the input\",\"; images does not have a data ignore value.\",\"; INPUT_RASTER1: in, required, type=ENVIRaster\",\"; Specify the first raster to use for intersection.\",\"; INPUT_RASTER2: in, required, type=ENVIRaster\",\"; Specify the second raster to use for intersection\",\"; OUTPUT_GRID_DEFINITION: out, optional, type=ENVIGridDefinition\",\"; Optionally return the ENVIGridDefinition object used to get the intersection\",\"; of the two scenes.\",\"; OUTPUT_RASTER1_URI: in, optional, type=string\",\"; Optionally specify the fully-qualified filepath\",\"; for the location of the first intersect raster.\",\"; OUTPUT_RASTER2_URI: in, optional, type=string\",\"; Optionally specify the fully-qualified filepath\",\"; for the location of the second intersect raster.\",\"; OUTPUT_MASK_RASTER_URI: in, optional, type=string\",\"; Optionally specify the fully-qualified filepath\",\"; for the location of the pixel state mask. Only applies\",\"; when `GENERATE_PIXEL_STATE_MASK` is set or one of the \",\"; input rasters does not have a data ignore value.\",\"; RESAMPLING: in, optional, type=string\",\"; Optionally return the ENVIGridDefinition object used to get the intersection\",\"; of the two scenes. Specify one of the following options:\",\"; - Nearest Neighbor\",\"; - Bilinear\",\"; - Cubic Convolution\",\";\",\"; :Tooltip:\",\"; Calculates the intersection of two rasters such that both\",\"; have the same spatial extent and spatial dimensions\",\";\",\"; :Author: Zachary Norman - GitHub: [znorman-harris](https://github.com/znorman-harris)\",\";-\",\"pro awesomeRasterIntersection, $\",\" DEBUG = debug,$\",\" DATA_IGNORE_VALUE = data_ignore_value,$\",\" GENERATE_PIXEL_STATE_MASK = generate_pixel_state_mask,$\",\" INPUT_RASTER1 = input_raster1,$\",\" INPUT_RASTER2 = input_raster2,$\",\" OUTPUT_MASK_RASTER_URI = output_mask_raster_uri,$\",\" OUTPUT_GRID_DEFINITION = output_grid_definition,$\",\" OUTPUT_RASTER1_URI = output_raster1_uri,$\",\" OUTPUT_RASTER2_URI = output_raster2_uri,$\",\" RESAMPLING = resampling\",\" compile_opt idl2, hidden\",\"end\",\"\"]}]}","complex-docs-example2.spec.ts":"{\"suiteName\":\"Complex real world test\",\"fileName\":\"complex-docs-example2.spec.ts\",\"tests\":[{\"name\":\"with past failure in complex docs\",\"code\":[\";+\",\"; :Description:\",\"; Function which will initialize the bdige_it object and start all bridges. When bridges are initialized\",\"; they are done so in parallel, but whe function will not return until every bridge is idle again.\",\";\",\"; :Params:\",\"; nbridges: in, required, type=int\",\"; The number of bridges that you want to create\",\";\",\"; :Keywords:\",\"; INIT : in, optional, type=strarr\",\"; Optional argument which allows you to pass in a string array of extra commands\",\"; to have each IDL_IDLBridge object execute upon creation.\",\"; MSG : in, optional, type=string\",\"; Optional argument to show the message prefix when a bridge process has completed for the TIME\",\"; keyword in bridge_it::run and bridge_it::run().\",\"; LOGDIR : in, optional, type=string\",\"; Specify the directory that the log file will be written to. The log file is just a text file with\",\"; all of the IDL Console output from each child process.\",\"; NREFRESH : in, optional, type=long\",\"; Specify the number of bridge processes to execute before closing and re-starting the\",\"; child process. Necessary for some ENVI routines so that we don't have memory fragmentation\",\"; regarding opening lots of small rasters.\",\"; PREFIX : in, optional, type=string, default='_KW_'\",\"; This optional keyword specifies the prefix which is used to differentiate between arguments and\",\"; keywords when it comes time to parse the arguments and keyword that will be passed into a routine.\",\";\",\"; :Author: Zachary Norman - GitHub: [znorman-harris](https://github.com/znorman-harris)\",\";\",\";-\",\"function bridge_it::Init, nbridges, INIT = init, MSG = msg, LOGDIR = logdir, NREFRESH = nrefresh, PREFIX = prefix\",\" compile_opt idl2, hidden\",\" on_error, 2\",\"\",\" return, 1\",\"end\"]}]}","document-vars.spec.ts":"{\"suiteName\":\"Correctly extract docs for\",\"fileName\":\"document-vars.spec.ts\",\"tests\":[{\"name\":\"variables with single-line block\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+ meaning of life\",\" a = 42\",\"end\"]},{\"name\":\"variables with multi-line block\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+\",\" ; Some things are really awesome\",\" ; and need a big description\",\" ;-\",\" a = 42\",\"end\"]},{\"name\":\"only use docs from first encounter\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+\",\" ; Some things are really awesome\",\" ; and need a big description\",\" ;-\",\" a = 42\",\"\",\" ;+ second docs are ignored\",\" a = 42\",\"end\"]}]}","functions.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"functions.spec.ts\",\"tests\":[{\"name\":\"functions\",\"code\":[\"function myfunc, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\"]}]}","function-methods.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"function-methods.spec.ts\",\"tests\":[{\"name\":\"function methods\",\"code\":[\"function myclass::mymethod, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\"]}]}","function-methods.init.spec.ts":"{\"suiteName\":\"Add function for\",\"fileName\":\"function-methods.init.spec.ts\",\"tests\":[{\"name\":\"class init methods\",\"code\":[\"function MyClass::init, a, b, c, kw2 = kw2\",\" compile_opt idl2\",\"\",\" ; set data type correctly for local variable\",\" z = MyClass()\",\"\",\" return, 1\",\"end\"]}]}","inherit-args-docs.spec.ts":"{\"suiteName\":\"Correctly inherits docs for\",\"fileName\":\"inherit-args-docs.spec.ts\",\"tests\":[{\"name\":\"arguments\",\"code\":[\"\",\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\";-\",\"pro mypro, var1\",\" compile_opt idl2\",\"end\",\"\"]}]}","inherit-kw-docs.spec.ts":"{\"suiteName\":\"Correctly inherits docs for\",\"fileName\":\"inherit-kw-docs.spec.ts\",\"tests\":[{\"name\":\"keywords\",\"code\":[\"\",\";+\",\"; My procedure\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, KW1=kw1\",\" compile_opt idl2\",\"end\",\"\"]}]}","inherit-private-docs.spec.ts":"{\"suiteName\":\"Correctly inherits docs for\",\"fileName\":\"inherit-private-docs.spec.ts\",\"tests\":[{\"name\":\"private\",\"code\":[\"\",\";+\",\"; My procedure\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean, private\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, KW1=kw1\",\" compile_opt idl2\",\"end\",\"\"]}]}","lambda.no-vars.spec.ts":"{\"suiteName\":\"With lambda functions\",\"fileName\":\"lambda.no-vars.spec.ts\",\"tests\":[{\"name\":\"do not extract variables\",\"code\":[\"; main level\",\"compile_opt idl2\",\"!null = lambda(n:n le 3 || min(n mod [2:fix(sqrt(n))]))\",\"end\"]}]}","main.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"main.spec.ts\",\"tests\":[{\"name\":\"main level\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"mypro, a, b, c, d\",\"end\"]}]}","notebook-parse.compile-opt.1.spec.ts":"{\"suiteName\":\"Verify notebook parsing\",\"fileName\":\"notebook-parse.compile-opt.1.spec.ts\",\"tests\":[{\"name\":\"adds compile-opt idl2 for main and gets right default type\",\"code\":[\"a = 42\",\"\",\"end\"],\"config\":{\"isNotebook\":true}}]}","notebook-parse.compile-opt.exceptions.spec.ts":"{\"suiteName\":\"Verify notebook parsing\",\"fileName\":\"notebook-parse.compile-opt.exceptions.spec.ts\",\"tests\":[{\"name\":\"ignores compile opt idl2 for procedures\",\"code\":[\"pro myPro\",\" print, 'Hello world'\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"ignores compile opt idl2 for functions\",\"code\":[\"function myPro\",\" print, 'Hello world'\",\" return 42\",\"end\"],\"config\":{\"isNotebook\":true}}]}","only-from-code.spec.ts":"{\"suiteName\":\"Only use code for docs\",\"fileName\":\"only-from-code.spec.ts\",\"tests\":[{\"name\":\"and exclude incorrectly documented parameters\",\"code\":[\";+\",\"; Header\",\";\",\"; :Args:\",\"; a: in, required, int\",\"; Some cool statement across\",\";\",\"; multiple lines\",\"; b: in, required, string\",\"; Some cool statement across\",\";\",\"; multiple lines\",\"; :Keywords:\",\"; kw1: in, required, int\",\"; Some cool statement across\",\";\",\"; multiple lines\",\"; kw2: in, required, string\",\"; Some cool statement across\",\";\",\"; multiple lines\",\";\",\"; :Author: Meeeeeeeeeeeeeeeeeee\",\"\",\"\",\"\",\"\",\"pro myPro, a, kw1 = kw1\",\"\",\"\",\" print, 'Hello world'\",\"\",\"\",\"end\"]}]}","parse-fast.ignore-docs.1.spec.ts":"{\"suiteName\":\"Verify fast parsing ignores docs\",\"fileName\":\"parse-fast.ignore-docs.1.spec.ts\",\"tests\":[{\"name\":\"for structures\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: Long\",\"; Placeholder docs for argument or keyword\",\"; prop2: ENVIRaster\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro mystruct__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"],\"config\":{\"full\":false}}]}","parse-fast.ignore-docs.2.spec.ts":"{\"suiteName\":\"Verify fast parsing ignores docs\",\"fileName\":\"parse-fast.ignore-docs.2.spec.ts\",\"tests\":[{\"name\":\"for procedures\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, envitask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idltask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, ENVITask | ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, IDLTask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, arg3, arg4, arg5, KW1 = kw1\",\" compile_opt idl3\",\"\",\"end\"],\"config\":{\"full\":false}}]}","parse-fast.ignore-docs.3.spec.ts":"{\"suiteName\":\"Verify fast parsing ignores docs\",\"fileName\":\"parse-fast.ignore-docs.3.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, envitask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idltask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, ENVITask | ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, IDLTask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myfunc, arg1, arg2, arg3, arg4, arg5, KW1 = kw1\",\" compile_opt idl3\",\" return, 42\",\"end\"],\"config\":{\"full\":false}}]}","populate-structures.1.spec.ts":"{\"suiteName\":\"Correctly populate structures\",\"fileName\":\"populate-structures.1.spec.ts\",\"tests\":[{\"name\":\"in class definitions\",\"code\":[\"pro mystruct__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"end\"]},{\"name\":\"with no properties\",\"code\":[\"pro mystruct__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct}\",\"end\"]}]}","populate-structures.2.spec.ts":"{\"suiteName\":\"Use docs for property types\",\"fileName\":\"populate-structures.2.spec.ts\",\"tests\":[{\"name\":\"in structures\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: Long\",\"; Placeholder docs for argument or keyword\",\"; prop2: ENVIRaster\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro mystruct__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]}]}","populate-structures.3.spec.ts":"{\"suiteName\":\"Find them in\",\"fileName\":\"populate-structures.3.spec.ts\",\"tests\":[{\"name\":\"normal procedures\",\"code\":[\"pro define_these_structures\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"end\"]}]}","populate-structures.4.spec.ts":"{\"suiteName\":\"Find them in\",\"fileName\":\"populate-structures.4.spec.ts\",\"tests\":[{\"name\":\"normal functions\",\"code\":[\"function define_these_structures\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"return, 1\",\"end\"]}]}","populate-structures.5.spec.ts":"{\"suiteName\":\"Find them in\",\"fileName\":\"populate-structures.5.spec.ts\",\"tests\":[{\"name\":\"procedure methods\",\"code\":[\"pro define_these_structures::method\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"end\"]}]}","populate-structures.6.spec.ts":"{\"suiteName\":\"Find them in\",\"fileName\":\"populate-structures.6.spec.ts\",\"tests\":[{\"name\":\"function methods\",\"code\":[\"function define_these_structures::method\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"return, 1\",\"end\"]}]}","populate-structures.7.spec.ts":"{\"suiteName\":\"Ignore them in\",\"fileName\":\"populate-structures.7.spec.ts\",\"tests\":[{\"name\":\"procedures\",\"code\":[\"pro my_def__define\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"if ~_exists then defsysv, '!notebook_magic', {IDLNotebookMagic}\",\"\",\"end\"]},{\"name\":\"as nested properties\",\"code\":[\"pro my_def__define\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"!null = {OtherStruct, prop:{SecondOtherStruct}}\",\"\",\"end\"]}]}","procedures.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"procedures.spec.ts\",\"tests\":[{\"name\":\"procedures\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]}]}","procedure-methods.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"procedure-methods.spec.ts\",\"tests\":[{\"name\":\"procedure methods\",\"code\":[\"pro myclass::mymethod, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]}]}","tasks.from-docs.spec.ts":"{\"suiteName\":\"Verify type parsing for\",\"fileName\":\"tasks.from-docs.spec.ts\",\"tests\":[{\"name\":\"ENVI and IDL Tasks in docs\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, envitask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idltask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, ENVITask | ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, IDLTask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, arg3, arg4, arg5\",\" compile_opt idl3\",\"\",\"end\"]}]}","tasks.guessing-from-code.spec.ts":"{\"suiteName\":\"Verify behaviors for task types\",\"fileName\":\"tasks.guessing-from-code.spec.ts\",\"tests\":[{\"name\":\"where we determine types from code\",\"code\":[\"compile_opt idl2\",\"\",\"mosaic1 = ENVITask('BuildMosaicRaster')\",\"mosaic2 = ENVITask(routine_dir() + 'buildmosaicraster.task')\",\"\",\"uri = 'buildmosaicraster.task'\",\"mosaic3 = ENVITask(uri)\",\"\",\"envitaskany1 = ENVITask(uri + uri)\",\"\",\"idlmosaic1 = IDLTask('BuildMosaicRaster')\",\"idlmosaic2 = IDLTask(routine_dir() + 'buildmosaicraster.task')\",\"\",\"idlmosaic3 = IDLTask(uri)\",\"\",\"idltaskany1 = IDLTask(uri + uri)\",\"end\"]}]}","types.from-args.spec.ts":"{\"suiteName\":\"Types from output arguments\",\"fileName\":\"types.from-args.spec.ts\",\"tests\":[{\"name\":\"and exclude incorrectly documented parameters\",\"code\":[\";+\",\"; :Arguments:\",\"; a: in, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\"; b: out, required, Long\",\"; Placeholder docs for argument, keyword, or property\",\"; c: out, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro auto_doc_example, a, b, c\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"auto_doc_example, arg1, arg2, arg3\",\"end\"]}]}","types.from-assignment-weird.spec.ts":"{\"suiteName\":\"Types from assignment\",\"fileName\":\"types.from-assignment-weird.spec.ts\",\"tests\":[{\"name\":\"where we define vars in-line\",\"code\":[\"; main level\",\"compile_opt idl2\",\"\",\"; any because using var before defined\",\"c = d + (d = 5)\",\"\",\"; number\",\"f = (g = 6) + g\",\"end\"]}]}","types.arrays.brackets.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.arrays.brackets.spec.ts\",\"tests\":[{\"name\":\"array creation using brackets\",\"code\":[\"pro array_creation\",\" compile_opt idl2\",\"\",\" ; long\",\" a = [1, 2, 3, 4]\",\"\",\" ; float\",\" b = [1, 2, 3, 4.]\",\"\",\" ; double\",\" c = [1, 2, 3, 4d]\",\"\",\" ; complex double\",\" d = [1, 2, 3, 4di]\",\"\",\" ; invalid\",\" e = [1, 2, 3, plot()]\",\"\",\" ; ignore if element has Null\",\" f = [1, 2, 3, !null, 4, 5]\",\"\",\" ; no nested arrays, just promoted\",\" g = [1, 2, 3, [1, 2, 3, 4d], 4, 5]\",\"\",\" ; array of lists\",\" h = [list(), list()]\",\"\",\" ; array of ENVIRasters\",\" i = [ENVIRaster(), ENVIRaster()]\",\"\",\" ; array of any\",\" j = [ENVIRaster(), plot()]\",\"end\"]}]}","types.arrays.edge-cases.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.arrays.edge-cases.spec.ts\",\"tests\":[{\"name\":\"array creation using edge cases that failed\",\"code\":[\"pro array_creation\",\" compile_opt idl2\",\"\",\" ; array of number\",\" a = [where(x)]\",\"end\"]},{\"name\":\"scalars or arrays can be used interchangeably\",\"code\":[\"pro array_creation\",\" compile_opt idl2\",\" e = envi()\",\" r = e.openRaster() ; scalar or array ENVIRaster\",\" ; array of ENVIRaster\",\" arr = [r]\",\"end\"]},{\"name\":\"allow all objects as long as no structures or all structures\",\"code\":[\"pro array_creation\",\" compile_opt idl2\",\" arr1 = [ENVIRaster(), ENVIMetaspectralRaster(), ENVISubsetRaster()]\",\" arr2 = [{}, {}]\",\"\",\" bad = [ENVIRaster(), ENVIMetaspectralRaster(), ENVISubsetRaster(), {}, 1]\",\"end\"]}]}","types.array-promotion.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.array-promotion.spec.ts\",\"tests\":[{\"name\":\"array promotion\",\"code\":[\";+\",\"; :Returns: ArrayPromotion\",\";\",\"; :Arguments:\",\"; a: bidirectional, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function test, a\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"compile_opt idl2\",\"\",\"; scalars\",\"scalar1 = test(1)\",\"\",\"; arrays\",\"array1 = test([1])\",\"array2 = test(bytarr(5))\",\"\",\"; either scalar or array\",\"c = made_up()\",\"either = test(c)\",\"\",\"end\"]}]}","types.from-foreach.spec.ts":"{\"suiteName\":\"Types from foreach loop\",\"fileName\":\"types.from-foreach.spec.ts\",\"tests\":[{\"name\":\"with type args 1\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]},{\"name\":\"with type args 2\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]},{\"name\":\"with non-index types returning original 1\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, String\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]},{\"name\":\"with non-index types returning original 2\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, Number\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]}]}","types.from-foreach.regression1.spec.ts":"{\"suiteName\":\"Types from foreach loop regression tests\",\"fileName\":\"types.from-foreach.regression1.spec.ts\",\"tests\":[{\"name\":\"with bad syntax\",\"code\":[\"pro \",\";+\",\"; :Arguments:\",\"; item: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]}]}","types.from-functions.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-functions.spec.ts\",\"tests\":[{\"name\":\"functions\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = ENVISubsetRaster()\",\"\",\" b = ENVITask('subsetraster')\",\"\",\" c = obj_new('envitask')\",\"\",\" d = keyword_set(5)\",\"\",\" e = dictionary()\",\"\",\" f = ENVITensorFlowModel()\",\"\",\" g = IDLTask('MyTask')\",\"\",\"end\"]},{\"name\":\"functions with other strings\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = ENVITask(\\\"subsetraster\\\")\",\"\",\" b = ENVITask(`subsetraster`)\",\"\",\" c = obj_new(\\\"envitask\\\")\",\"\",\" d = obj_new(`envitask`)\",\"\",\" e = IDLTask(\\\"MyTask\\\")\",\"\",\" f = IDLTask(`MyTask`)\",\"\",\"end\"]}]}","types.from-numbers.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-numbers.spec.ts\",\"tests\":[{\"name\":\"numbers\",\"code\":[\"pro pro4\",\"compile_opt idl2\",\"\",\"; byte\",\"byte1 = 0b\",\"byte2 = 0ub\",\"\",\"; integer\",\"int1 = 0s\",\"\",\"; compile option\",\"compOptLong = 0\",\"\",\"; uint\",\"uint1 = 0u\",\"uint2 = 0us\",\"\",\"; long\",\"long1 = 0l\",\"\",\"; ulong\",\"ulong1 = 0ul\",\"\",\"; long64\",\"long641 = 0ll\",\"\",\"; ulong64\",\"ulong641 = 0ull\",\"\",\"; float\",\"float1 = 1.\",\"float2 = .1\",\"float3 = 1.1\",\"float4 = 10e\",\"float5 = 10e5\",\"float6 = 10.e-3\",\"float7 = .1e+12\",\"float8 = 2.3e12\",\"\",\"; double\",\"double0 = 1d\",\"double1 = 1.d\",\"double2 = .1d\",\"double3 = 1.1d\",\"double4 = 10d\",\"double5 = 10d5\",\"double6 = 10.d-3\",\"double7 = .1d+12\",\"double8 = 2.3d12\",\"\",\"; binary\",\"binary1 = '10101'b\",\"binary2 = \\\"10101\\\"b\",\"\",\"; hex\",\"hex1 = '10101'x\",\"hex2 = '7FFF'XS\",\"hex3 = '8FFF'XS\",\"hex4 = \\\"10101\\\"x\",\"hex5 = 0x\",\"hex6 = 0x7FFF\",\"\",\"; octal\",\"octal1 = \\\"36\",\"octal2 = \\\"36b\",\"octal3 = \\\"345ull\",\"octal4 = '10101'o\",\"octal5 = \\\"10101\\\"o\",\"octal6 = 0o\",\"octal7 = 0o7FFF\",\"end\"]},{\"name\":\"numbers with no compile opt\",\"code\":[\"pro pro1\",\"compile_opt\",\"; compile option\",\"compOptInt = 0\",\"end\"]},{\"name\":\"numbers with float64 compile opt\",\"code\":[\"pro pro2\",\"compile_opt float64\",\"; compile option\",\"compOptDouble = 0\",\"\",\"; float\",\"float1 = 1.\",\"float2 = .1\",\"float3 = 1.1\",\"float4 = 10e\",\"float5 = 10e5\",\"float6 = 10.e-3\",\"float7 = .1e+12\",\"float8 = 2.3e12\",\"end\"]},{\"name\":\"numbers with idl3 compile opt\",\"code\":[\"pro pro3\",\"compile_opt idl3\",\"; compile option\",\"compOptDouble = 0\",\"\",\"; float\",\"float1 = 1.\",\"float2 = .1\",\"float3 = 1.1\",\"float4 = 10e\",\"float5 = 10e5\",\"float6 = 10.e-3\",\"float7 = .1e+12\",\"float8 = 2.3e12\",\"end\"]}]}","types.from-numbers-complex1.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-numbers-complex1.spec.ts\",\"tests\":[{\"name\":\"complex numbers using \\\"i\\\"\",\"code\":[\"pro pro5\",\"compile_opt idl2\",\"\",\"; byte\",\"byte1 = 0bi\",\"byte2 = 0ubi\",\"\",\"; integer\",\"int1 = 0si\",\"\",\"; compile option\",\"compOptLong = 0i\",\"\",\"; uint\",\"uint1 = 0ui\",\"uint2 = 0usi\",\"\",\"; long\",\"long1 = 0li\",\"\",\"; ulong\",\"ulong1 = 0uli\",\"\",\"; long64\",\"long641 = 0lli\",\"\",\"; ulong64\",\"ulong641 = 0ulli\",\"\",\"; float\",\"float1 = 1.i\",\"float2 = .1i\",\"float3 = 1.1i\",\"float4 = 10ei\",\"float5 = 10e5i\",\"float6 = 10.e-3i\",\"float7 = .1e+12i\",\"float8 = 2.3e12i\",\"\",\"; double\",\"double0 = 1di\",\"double1 = 1.di\",\"double2 = .1di\",\"double3 = 1.1di\",\"double4 = 10di\",\"double5 = 10d5i\",\"double6 = 10.d-3i\",\"double7 = .1d+12i\",\"double8 = 2.3d12i\",\"end\"]}]}","types.from-numbers-complex2.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-numbers-complex2.spec.ts\",\"tests\":[{\"name\":\"complex numbers using \\\"j\\\"\",\"code\":[\"pro pro6\",\"compile_opt idl2\",\"\",\"; byte\",\"byte1 = 0bj\",\"byte2 = 0ubj\",\"\",\"; jnteger\",\"jnt1 = 0sj\",\"\",\"; compjle optjon\",\"compOptLong = 0j\",\"\",\"; ujnt\",\"ujnt1 = 0uj\",\"ujnt2 = 0usj\",\"\",\"; long\",\"long1 = 0lj\",\"\",\"; ulong\",\"ulong1 = 0ulj\",\"\",\"; long64\",\"long641 = 0llj\",\"\",\"; ulong64\",\"ulong641 = 0ullj\",\"\",\"; float\",\"float1 = 1.j\",\"float2 = .1j\",\"float3 = 1.1j\",\"float4 = 10ej\",\"float5 = 10e5j\",\"float6 = 10.e-3j\",\"float7 = .1e+12j\",\"float8 = 2.3e12j\",\"\",\"; double\",\"double0 = 1dj\",\"double1 = 1.dj\",\"double2 = .1dj\",\"double3 = 1.1dj\",\"double4 = 10dj\",\"double5 = 10d5j\",\"double6 = 10.d-3j\",\"double7 = .1d+12j\",\"double8 = 2.3d12j\",\"end\"]}]}","types.from-properties.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-properties.spec.ts\",\"tests\":[{\"name\":\"properties\",\"code\":[\";+\",\"; :Arguments:\",\"; a: in, required, ENVIRaster\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4, a\",\" compile_opt idl2\",\"\",\" ; properties\",\" p1 = a.metadata\",\" p2 = p1.count\",\" p3 = (a.metadata)\",\" p4 = a.metadata.count\",\"end\"]}]}","types.from-properties2.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-properties2.spec.ts\",\"tests\":[{\"name\":\"properties of anonymous structures\",\"code\":[\"pro pro4\",\" compile_opt idl2\",\" a = {a: 'string', $\",\" b: `string`}\",\"\",\" ; properties\",\" p1 = a.a\",\" p2 = p1.length\",\" p3 = (a.b)\",\" p4 = a.b\",\"end\"]}]}","types.from-type-of-arg.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-type-of-arg.spec.ts\",\"tests\":[{\"name\":\"type-of-arg case without args (default to first)\",\"code\":[\";+\",\"; :Returns: TypeOfArg\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"\",\"string = myfunc('string')\",\"any = myfunc()\",\"float = myfunc(1.0)\",\"array = myfunc([1, 2, 3])\",\"end\"]},{\"name\":\"type-of-arg case specifying arg\",\"code\":[\";+\",\"; :Returns: TypeOfArg<0>\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"\",\"string = myfunc('string')\",\"any = myfunc()\",\"float = myfunc(1.0)\",\"array = myfunc([1, 2, 3])\",\"end\"]},{\"name\":\"type-of-arg case invalid arg uses any\",\"code\":[\";+\",\"; :Returns: TypeOfArg<2>\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"\",\"string = myfunc('string')\",\"any = myfunc()\",\"float = myfunc(1.0)\",\"array = myfunc([1, 2, 3])\",\"end\"]},{\"name\":\"type-of-arg case non-number index\",\"code\":[\";+\",\"; :Returns: TypeOfArg\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"\",\"string = myfunc('string')\",\"any = myfunc()\",\"float = myfunc(1.0)\",\"array = myfunc([1, 2, 3])\",\"end\"]}]}","types.from-type-args.edge-cases1.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-type-args.edge-cases1.spec.ts\",\"tests\":[{\"name\":\"type without type args\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, List<>\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\"end\"]}]}","types.indexing.arrays.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.arrays.spec.ts\",\"tests\":[{\"name\":\"indexing arrays\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro arrays, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.dictionaries.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.dictionaries.spec.ts\",\"tests\":[{\"name\":\"dictionaries\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, Dictionary\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro dictionaries, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.hashes.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.hashes.spec.ts\",\"tests\":[{\"name\":\"hashes\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro34, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.lists.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.lists.spec.ts\",\"tests\":[{\"name\":\"lists\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro lists, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.ordered-hashes.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.ordered-hashes.spec.ts\",\"tests\":[{\"name\":\"ordered hashes\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro ordered_hashes, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.properties.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.properties.spec.ts\",\"tests\":[{\"name\":\"property indexing\",\"code\":[\"pro mypro1\",\" compile_opt idl2\",\" ; number or array of numbers\",\" index = where('5' eq fn)\",\" ; any\",\" x = (!null).(1)[index]\",\"end\",\"\"]}]}","types.indexing.edge-cases.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.edge-cases.spec.ts\",\"tests\":[{\"name\":\"indexing compound types\",\"code\":[\"compile_opt idl2\",\"; should be number\",\"rb_match = (where(5 eq [1, 2, 3, 4, 5]))[0]\",\"end\",\"\"]},{\"name\":\"scalar with array\",\"code\":[\"compile_opt idl2\",\"polyColors = 5l\",\"array1 = polyColors[idx : nMax]\",\"array2 = polyColors[[5 : 15: 1]]\",\"end\",\"\"]}]}","types.keywords.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.keywords.spec.ts\",\"tests\":[{\"name\":\"output or bidirectional keywords\",\"code\":[\";+\",\"; :Description:\",\"; Constructor\",\";\",\"; :Returns:\",\"; myclass\",\";\",\";-\",\"function myclass::Init\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw: out, optional, Array\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myclass::method, kw = kw\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw: out, optional, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro myclass::method, kw = kw\",\" compile_opt idl2\",\"end\",\"\",\";+\",\"; :Description:\",\"; Class definition procedure\",\";\",\";-\",\"pro myclass__define\",\" compile_opt idl2\",\"\",\" struct = {myclass}\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw: out, optional, Long\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myfunc, kw = kw\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw: out, optional, Byte\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro mypro, kw = kw\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main level program\",\"compile_opt idl2\",\"\",\"; procedures\",\"mypro, kw = a\",\"\",\"; functions\",\"!null = myfunc(kw = b)\",\"\",\"; make class for methods\",\"var = myclass()\",\"\",\"; procedure methods\",\"var.method, kw = c\",\"\",\"; function methods\",\"!null = var.method(kw = d)\",\"end\"]}]}","types.operations.structures.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.structures.spec.ts\",\"tests\":[{\"name\":\"structure operations\",\"code\":[\"pro struct_checks\",\"compile_opt idl2\",\"\",\"str = {a: 42}\",\"\",\"a = 1 + str\",\"\",\"b = str + {a: 42}\",\"\",\"c = str + list()\",\"\",\"d = str + hash()\",\"\",\"e = str + orderedhash()\",\"\",\"f = str + dictionary()\",\"end\"]}]}","types.operations.list.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.list.spec.ts\",\"tests\":[{\"name\":\"list operations\",\"code\":[\"pro list_checks\",\"compile_opt idl2\",\"\",\"a = 1 + list()\",\"\",\"b = list() + list()\",\"\",\"c = list() + hash()\",\"\",\"d = list() + orderedhash()\",\"\",\"e = list() + dictionary()\",\"end\"]}]}","types.operations.hash.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.hash.spec.ts\",\"tests\":[{\"name\":\"hash operations\",\"code\":[\"pro hash_checks\",\"compile_opt idl2\",\"\",\"a = 1 + hash()\",\"\",\"b = hash() + list()\",\"\",\"c = hash() + hash()\",\"\",\"d = hash() + orderedhash()\",\"\",\"e = hash() + dictionary()\",\"end\"]}]}","types.operations.ordered-hash.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.ordered-hash.spec.ts\",\"tests\":[{\"name\":\"ordered hash operations\",\"code\":[\"pro orderedhash_checks\",\"compile_opt idl2\",\"\",\"a = 1 + orderedhash()\",\"\",\"b = orderedhash() + list()\",\"\",\"c = orderedhash() + hash()\",\"\",\"d = orderedhash() + orderedhash()\",\"\",\"e = orderedhash() + dictionary()\",\"end\"]}]}","types.operations.dictionary.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.dictionary.spec.ts\",\"tests\":[{\"name\":\"dictionary operations\",\"code\":[\"pro dictionary_checks\",\"compile_opt idl2\",\"\",\"a = 1 + dictionary()\",\"\",\"b = dictionary() + list()\",\"\",\"c = dictionary() + hash()\",\"\",\"d = dictionary() + orderedhash()\",\"\",\"e = dictionary() + dictionary()\",\"end\"]}]}","types.parsing-checks.1.spec.ts":"{\"suiteName\":\"Cases to make sure we always parse our types correctly\",\"fileName\":\"types.parsing-checks.1.spec.ts\",\"tests\":[{\"name\":\"for normal cases\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Pointer>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Number | String\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, Hash | List>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg7: in, required, Hash | List | List>\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro type_parsing_test, arg1, arg2, arg3, arg4, arg5, arg6, arg7\",\" compile_opt idl3\",\"\",\"end\"]}]}","types.pointer-de-ref.1.spec.ts":"{\"suiteName\":\"Get types correctly from pointer de-reference\",\"fileName\":\"types.pointer-de-ref.1.spec.ts\",\"tests\":[{\"name\":\"for normal cases\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Pointer | String\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, Pointer | Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg7: in, required, Pointer | Pointer\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pointers, arg1, arg2, arg3, arg4, arg5, arg6, arg7\",\" compile_opt idl3\",\"\",\" ; number\",\" a = *arg1\",\"\",\" ; enviraster\",\" b = *arg3[0]\",\"\",\" ; and, unable to index\",\" c = arg1[0]\",\"\",\" ; any, unable to de-reference\",\" d = *5\",\"\",\" ; any, ambiguous de-reference\",\" e = *arg4\",\"\",\" ; any\",\" f = *arg5\",\"\",\" ; union of type args\",\" g = *arg6\",\"\",\" ; union of type args, dont show arg7 more string more than once\",\" g = *arg7\",\"end\"]}]}","types.promotion1.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.promotion1.spec.ts\",\"tests\":[{\"name\":\"type promotion\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Arguments:\",\"; a: in, required, Number\",\"; Placeholder docs for argument, keyword, or property\",\"; b: in, required, ComplexNumber\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function most_cases, a, b\",\" compile_opt idl2\",\"\",\" byte = 's' + 1b\",\"\",\" int = 's' + 1s\",\"\",\" uint = 's' + 1us\",\"\",\" long = 's' + 1l\",\"\",\" ulong = 's' + 1ul\",\"\",\" long64 = 's' + 1ll\",\"\",\" ulong64 = 's' + 1ull\",\"\",\" float1 = 's' + 1.\",\" float2 = 's' + 1e\",\"\",\" double = 's' + 1d\",\"\",\" biginteger = 's' + BigInteger(5)\",\"\",\" number = 's' + a\",\"\",\" complexfloat = 's' + 1.i\",\"\",\" complexdouble = 's' + 1di\",\" complexdouble = 's' + 1dj\",\"\",\" complexnumber1 = 's' + a + 1di + 1dj\",\" complexnumber2 = a + b\",\"\",\" return, 1\",\"end\"]}]}","types.strings.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.strings.spec.ts\",\"tests\":[{\"name\":\"strings\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = 'single quote'\",\"\",\" b = \\\"double quote\\\"\",\"\",\" c = `literal string`\",\"\",\"end\"]}]}","types.ternary.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.ternary.spec.ts\",\"tests\":[{\"name\":\"ternary\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" ; long or envi\",\" a = !true ? 5 + 15 : envi()\",\"\",\" ; long or string\",\" b = !true ? 5 + 15 : 'string'\",\"\",\" ; string\",\" c = !true ? 'string' : 'false'\",\"\",\" ; number\",\" d = !true ? 5 : 6\",\"\",\" ; any\",\" e = !true ? 5 \",\"\",\" ; any\",\" f = !true ? 5 :\",\"\",\"end\"]}]}","types.variables.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.variables.spec.ts\",\"tests\":[{\"name\":\"variables\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = ENVISubsetRaster()\",\"\",\" b = a\",\"end\"]}]}","types.static-classes.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.static-classes.spec.ts\",\"tests\":[{\"name\":\"named static classes methods/properties\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = IDL_Number.ndim\",\" b = envi.openRaster()\",\" any1 = image ; nothing\",\"end\"]}]}","types.structure-names.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.structure-names.spec.ts\",\"tests\":[{\"name\":\"named structures\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = {ENVIRaster}\",\"\",\" b = {!map}\",\"end\"]}]}","types.structure-anonymous.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.structure-anonymous.spec.ts\",\"tests\":[{\"name\":\"anonymous structures\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = {a: 'string', $\",\" b: `string`}\",\"\",\"end\"]}]}","types.system-variables.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.system-variables.spec.ts\",\"tests\":[{\"name\":\"the !null system variable\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = !null\",\"end\"]},{\"name\":\"system variables that are structures\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = !x\",\"end\"]}]}"},"auto-outline-tests":{"ex-1.spec.ts":"{\"suiteName\":\"Extracts outline\",\"fileName\":\"ex-1.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/awesomerasterintersection.pro\"}]}","ex-2.spec.ts":"{\"suiteName\":\"Extracts outline with main\",\"fileName\":\"ex-2.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/myfunc.pro\"}]}","ex-3.spec.ts":"{\"suiteName\":\"Extracts outline\",\"fileName\":\"ex-3.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens with multiple parent routines\",\"file\":\"idl/test/hover-help/mypro.pro\"}]}"},"auto-semantic-token-tests":{"basic.spec.ts":"{\"suiteName\":\"Extracts semantic tokens\",\"fileName\":\"basic.spec.ts\",\"tests\":[{\"name\":\"for basic case\",\"code\":[\"compile_opt idl2\",\"a = envi.api_version\",\"!null = envi.openRaster('somefile.dat')\",\"end\"]}]}"},"auto-task-parsing-tests":{"envi1.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"envi1.spec.ts\",\"tests\":[{\"name\":\"envi\",\"file\":\"idl/test/task-parsing/BuildMosaicRaster.task\"}]}","envi2.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"envi2.spec.ts\",\"tests\":[{\"name\":\"envi\",\"file\":\"idl/test/task-parsing/ExportRasterToCADRG.task\"}]}","envi3.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"envi3.spec.ts\",\"tests\":[{\"name\":\"envi\",\"file\":\"idl/test/task-parsing/PointCloudFeatureExtraction.task\"}]}","envi4.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"envi4.spec.ts\",\"tests\":[{\"name\":\"envi\",\"file\":\"idl/test/task-parsing/SetRasterMetadata.task\"}]}","idl1.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"idl1.spec.ts\",\"tests\":[{\"name\":\"idl\",\"file\":\"idl/test/task-parsing/Download_S3_URL.task\"}]}","idl2.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"idl2.spec.ts\",\"tests\":[{\"name\":\"idl\",\"file\":\"idl/test/task-parsing/QueryAllTasks.task\"}]}","idl3.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"idl3.spec.ts\",\"tests\":[{\"name\":\"idl\",\"file\":\"idl/test/task-parsing/QueryTask.task\"}]}"},"auto-assembler-tests":{"auto-doc.args.spec.ts":"{\"suiteName\":\"Verify arg formatting\",\"fileName\":\"auto-doc.args.spec.ts\",\"tests\":[{\"name\":\"matches arg definitions\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, ARG3\",\" compile_opt idl3\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.basic.spec.ts":"{\"suiteName\":\"Verify doc formatting\",\"fileName\":\"auto-doc.basic.spec.ts\",\"tests\":[{\"name\":\"close and auto populate existing docs block\",\"code\":[\";+\",\";\",\"function myPro, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\" return, 42\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"capture default content and re-work\",\"code\":[\";+\",\"; Header\",\";-\",\"pro myPro\",\" compile_opt idl2\",\" print, 'Hello world'\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"add docs for procedures automatically\",\"code\":[\"pro myPro, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\" return, 42\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"add docs for functions automatically\",\"code\":[\"function myPro2, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\" return, 42\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"add docs for multiple routines at once\",\"code\":[\"pro myPro, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\"end\",\"\",\"function myPro2, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\" return, 42\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"handle, and format correctly, multi-line headers\",\"code\":[\";+\",\"; :Something fancy:\",\"; Really cool information \",\"; sdf\",\";-\",\"pro test_things\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\" uses proper external name for keyword in auto-docs\",\"code\":[\"pro test_things2, a, b, kw2 = kw222\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\" for only arguments\",\"code\":[\"pro test_things2, a, b\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\" for only keywords\",\"code\":[\"pro test_things2, kw222=kw2, kw3 = kw3\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.example-code.spec.ts":"{\"suiteName\":\"Verify formatting\",\"fileName\":\"auto-doc.example-code.spec.ts\",\"tests\":[{\"name\":\"for example blocks moves\",\"code\":[\"; TODO: something\",\"pro test_things, a, b, c\",\" compile_opt idl2\",\"end\",\"\",\";+\",\"; :Description:\",\"; My favorite procedure\",\"; \",\"; \",\"; \",\"; :Examples:\",\"; \",\"; Open an image in ENVI and display in a notebook:\",\"; \",\"; ```idl\",\"; ; Start the application\",\"; e = envi(/headless)\",\"; \",\"; ; Open an input file\",\"; file = filepath('qb_boulder_msi', subdir = ['data'], $\",\"; root_dir = e.root_dir)\",\"; raster = e.openRaster(File)\",\"; \",\"; ; display in the current notebook cell\",\"; e.displayInNotebook, raster\",\"; ```\",\";-\",\"pro test_things2\",\" compile_opt idl2\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.complex2.spec.ts":"{\"suiteName\":\"Verify complex formatting\",\"fileName\":\"auto-doc.complex2.spec.ts\",\"tests\":[{\"name\":\"moves things correctly\",\"code\":[\"; TODO: something\",\"pro test_things, a, b, c\",\" compile_opt idl2\",\"end\",\"\",\";+\",\";-\",\"pro test_things2\",\" compile_opt idl2\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.complex3.spec.ts":"{\"suiteName\":\"Verify complex formatting\",\"fileName\":\"auto-doc.complex3.spec.ts\",\"tests\":[{\"name\":\"moves main level correctly\",\"code\":[\"; TODO: something\",\"pro test_things\",\"end\",\"\",\"compile_opt idl2\",\"\",\"test_things\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.complex4.spec.ts":"{\"suiteName\":\"Verify complex formatting\",\"fileName\":\"auto-doc.complex4.spec.ts\",\"tests\":[{\"name\":\"moves main level correctly\",\"code\":[\";+\",\"; :Description:\",\"; Function which will initialize the bdige_it object and start all bridges. When bridges are initialized\",\"; they are done so in parallel, but whe function will not return until every bridge is idle again.\",\";\",\"; :Params:\",\"; nbridges: in, required, type=int\",\"; The number of bridges that you want to create\",\";\",\"; :Keywords:\",\"; INIT : in, optional, type=strarr\",\"; Optional argument which allows you to pass in a string array of extra commands\",\"; to have each IDL_IDLBridge object execute upon creation.\",\"; MSG : in, optional, type=string\",\"; Optional argument to show the message prefix when a bridge process has completed for the TIME\",\"; keyword in bridge_it::run and bridge_it::run().\",\"; LOGDIR : in, optional, type=string\",\"; Specify the directory that the log file will be written to. The log file is just a text file with\",\"; all of the IDL Console output from each child process.\",\"; NREFRESH : in, optional, type=long\",\"; Specify the number of bridge processes to execute before closing and re-starting the\",\"; child process. Necessary for some ENVI routines so that we don't have memory fragmentation\",\"; regarding opening lots of small rasters.\",\"; PREFIX : in, optional, type=string, default='_KW_'\",\"; This optional keyword specifies the prefix which is used to differentiate between arguments and\",\"; keywords when it comes time to parse the arguments and keyword that will be passed into a routine.\",\";\",\"; :Author: Zachary Norman - GitHub: [znorman-harris](https://github.com/znorman-harris)\",\";\",\";-\",\"function bridge_it::Init, nbridges, INIT = init, MSG = msg, LOGDIR = logdir, NREFRESH = nrefresh, PREFIX = prefix\",\" compile_opt idl2, hidden\",\" on_error, 2\",\"\",\" return, 1\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.non-idl-display-names.spec.ts":"{\"suiteName\":\"Verify type formatting uses display names\",\"fileName\":\"auto-doc.non-idl-display-names.spec.ts\",\"tests\":[{\"name\":\"matches arg definitions\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, enviraster\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idl_variable\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, plot\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, arg3\",\" compile_opt idl3\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.only.spec.ts":"{\"suiteName\":\"Only use AutoDoc\",\"fileName\":\"auto-doc.only.spec.ts\",\"tests\":[{\"name\":\"and leave everything else the same\",\"code\":[\"function dist,n,m ;Return a rectangular array in which each pixel = euclidian\",\";distance from the origin.\",\"compile_opt idl2\",\"\",\"on_error,2 ;Return to caller if an error occurs\",\"\",\"n1 = n[0]\",\"m1 = (n_elements(m) le 0) ? n1 : m[0]\",\"x=findgen(n1) ;Make a row\",\"x = (x < (n1-x)) ^ 2 ;column squares\",\"\",\"a = FLTARR(n1,m1,/NOZERO) ;Make array\",\"\",\"for i=0L, m1/2 do begin ;Row loop\",\"y = sqrt(x + i^2.) ;Euclidian distance\",\"a[0,i] = y ;Insert the row\",\"if i ne 0 then a[0, m1-i] = y ;Symmetrical\",\"endfor\",\"return,a\",\"end\"],\"config\":{\"autoDoc\":true,\"styleAndFormat\":false}}]}","auto-doc.only2.spec.ts":"{\"suiteName\":\"Only use AutoDoc\",\"fileName\":\"auto-doc.only2.spec.ts\",\"tests\":[{\"name\":\"and dont fix problems\",\"code\":[\"pro test, a, b, c\",\"end\",\"\",\"test\",\"end\"],\"config\":{\"autoDoc\":true,\"styleAndFormat\":false,\"autoFix\":false}}]}","auto-doc.parameters.spec.ts":"{\"suiteName\":\"Verify parameter formatting\",\"fileName\":\"auto-doc.parameters.spec.ts\",\"tests\":[{\"name\":\"sort arguments by appearance and add bad at the end\",\"code\":[\";+\",\"; :Args:\",\"; a: in, required, int, private\",\"; Some cool statement\",\"; b: in, required, string\",\"; Some cool statement\",\"; c: in, required, int, private\",\"; Some cool statement\",\";\",\";-\",\"pro myPro, a, c\",\" compile_opt idl2\",\" print, 'Hello world'\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"sort keywords alphabetically and add bad at the end\",\"code\":[\";+\",\"; :Keywords:\",\"; kw2: in, required, int\",\"; Some cool statement\",\"; kw: in, required, string\",\"; Some cool statement across\",\";\",\"; multiple lines\",\"; kw1: in, required, string\",\"; Some cool statement across\",\";\",\";-\",\"pro myPro, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.order-args.spec.ts":"{\"suiteName\":\"Verify arg ordering\",\"fileName\":\"auto-doc.order-args.spec.ts\",\"tests\":[{\"name\":\"matches the argument definition\",\"code\":[\";+\",\"; :Arguments:\",\"; a01: in, required, any\",\"; Placeholder docs for argument or keyword\",\"; a02: in, required, array\",\"; Placeholder docs for argument or keyword\",\"; a03: in, required, bigint\",\"; Placeholder docs for argument or keyword\",\"; a04: in, required, biginteger\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro my_thing, $\",\" a03, a04, a01, a02\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.task-types.spec.ts":"{\"suiteName\":\"Verify type formatting for\",\"fileName\":\"auto-doc.task-types.spec.ts\",\"tests\":[{\"name\":\"ENVI and IDL Tasks\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, envitask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idltask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, ENVITask | ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, IDLTask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, arg3, arg4, arg5\",\" compile_opt idl3\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.types.spec.ts":"{\"suiteName\":\"Verify type formatting\",\"fileName\":\"auto-doc.types.spec.ts\",\"tests\":[{\"name\":\"parses and gives normalized appearance for all IDL types\",\"code\":[\";+\",\"; :Arguments:\",\"; a01: in, required, any\",\"; Placeholder docs for argument or keyword\",\"; a02: in, required, array\",\"; Placeholder docs for argument or keyword\",\"; a03: in, required, bigint\",\"; Placeholder docs for argument or keyword\",\"; a04: in, required, biginteger\",\"; Placeholder docs for argument or keyword\",\"; a05: in, required, binary\",\"; Placeholder docs for argument or keyword\",\"; a06: in, required, bool\",\"; Placeholder docs for argument or keyword\",\"; a07: in, required, boolean\",\"; Placeholder docs for argument or keyword\",\"; a08: in, required, byte\",\"; Placeholder docs for argument or keyword\",\"; a09: in, required, complex\",\"; Placeholder docs for argument or keyword\",\"; a10: in, required, dcomplex\",\"; Placeholder docs for argument or keyword\",\"; a11: in, required, doublecomplex\",\"; Placeholder docs for argument or keyword\",\"; a12: in, required, dict\",\"; Placeholder docs for argument or keyword\",\"; a13: in, required, dictionary\",\"; Placeholder docs for argument or keyword\",\"; a14: in, required, float64\",\"; Placeholder docs for argument or keyword\",\"; a15: in, required, double\",\"; Placeholder docs for argument or keyword\",\"; a16: in, required, float32\",\"; Placeholder docs for argument or keyword\",\"; a17: in, required, float\",\"; Placeholder docs for argument or keyword\",\"; a18: in, required, hash\",\"; Placeholder docs for argument or keyword\",\"; a19: in, required, hex\",\"; Placeholder docs for argument or keyword\",\"; a20: in, required, int\",\"; Placeholder docs for argument or keyword\",\"; a21: in, required, integer\",\"; Placeholder docs for argument or keyword\",\"; a22: in, required, list\",\"; Placeholder docs for argument or keyword\",\"; a23: in, required, long\",\"; Placeholder docs for argument or keyword\",\"; a24: in, required, long64\",\"; Placeholder docs for argument or keyword\",\"; a25: in, required, null\",\"; Placeholder docs for argument or keyword\",\"; a26: in, required, number\",\"; Placeholder docs for argument or keyword\",\"; a27: in, required, class\",\"; Placeholder docs for argument or keyword\",\"; a28: in, required, object\",\"; Placeholder docs for argument or keyword\",\"; a29: in, required, octal\",\"; Placeholder docs for argument or keyword\",\"; a30: in, required, orderedhash\",\"; Placeholder docs for argument or keyword\",\"; a31: in, required, pointer\",\"; Placeholder docs for argument or keyword\",\"; a32: in, required, string\",\"; Placeholder docs for argument or keyword\",\"; a33: in, required, structure\",\"; Placeholder docs for argument or keyword\",\"; a34: in, required, uint\",\"; Placeholder docs for argument or keyword\",\"; a35: in, required, unsignedint\",\"; Placeholder docs for argument or keyword\",\"; a36: in, required, unsignedinteger\",\"; Placeholder docs for argument or keyword\",\"; a37: in, required, ulong\",\"; Placeholder docs for argument or keyword\",\"; a38: in, required, unsignedlong\",\"; Placeholder docs for argument or keyword\",\"; a39: in, required, ulong64\",\"; Placeholder docs for argument or keyword\",\"; a40: in, required, unsignedlong64\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro my_thing, $\",\" a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, $\",\" a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, $\",\" a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, $\",\" a31, a32, a33, a34, a35, a36, a37, a38, a39, a40\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.non-idl-doc.spec.ts":"{\"suiteName\":\"Verify doc formatting\",\"fileName\":\"auto-doc.non-idl-doc.spec.ts\",\"tests\":[{\"name\":\"for non IDL Doc styled docs\",\"code\":[\";+\",\"; NAME:\",\"; DIST\",\";\",\"; PURPOSE:\",\"; Create a rectangular array in which each element is proportional\",\"; to its frequency. This array may be used for a variety\",\"; of purposes, including frequency-domain filtering and\",\"; making pretty pictures.\",\";\",\"; CATEGORY:\",\"; Signal Processing.\",\";\",\"; CALLING SEQUENCE:\",\"; Result = DIST(N [, M])\",\";\",\"; INPUTS:\",\"; N = number of columns in result.\",\"; M = number of rows in result. If omitted, N is used to return\",\"; a square array.\",\";\",\"; OUTPUTS:\",\"; Returns an (N,M) floating array in which:\",\";\",\"; R(i,j) = SQRT(F(i)^2 + G(j)^2) where:\",\"; F(i) = i IF 0 <= i <= n/2\",\"; = n-i IF i > n/2\",\"; G(i) = i IF 0 <= i <= m/2\",\"; = m-i IF i > m/2\",\";\",\"; SIDE EFFECTS:\",\"; None.\",\";\",\"; RESTRICTIONS:\",\"; None.\",\";\",\"; PROCEDURE:\",\"; Straightforward. The computation is done a row at a time.\",\";\",\"; MODIFICATION HISTORY:\",\"; Very Old.\",\"; SMR, March 27, 1991 - Added the NOZERO keyword to increase efficiency.\",\"; (Recomended by Wayne Landsman)\",\"; DMS, July, 1992. - Added M parameter to make non-square arrays.\",\"; CT, RSI, March 2000: Changed i^2 to i^2. to avoid overflow.\",\";-\",\"function dist,n,m ;Return a rectangular array in which each pixel = euclidian\",\" ;distance from the origin.\",\"compile_opt idl2\",\"\",\"on_error,2 ;Return to caller if an error occurs\",\"\",\"n1 = n[0]\",\"m1 = (n_elements(m) le 0) ? n1 : m[0]\",\"x=findgen(n1) ;Make a row\",\"x = (x < (n1-x)) ^ 2 ;column squares\",\"\",\"a = FLTARR(n1,m1,/NOZERO) ;Make array\",\"\",\"for i=0L, m1/2 do begin ;Row loop\",\" y = sqrt(x + i^2.) ;Euclidian distance\",\" a[0,i] = y ;Insert the row\",\" if i ne 0 then a[0, m1-i] = y ;Symmetrical\",\"endfor\",\"return,a\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.format-keywords.spec.ts":"{\"suiteName\":\"Apply keyword formatting\",\"fileName\":\"auto-doc.format-keywords.spec.ts\",\"tests\":[{\"name\":\"so docs match code style\",\"code\":[\";+\",\"; :Description:\",\"; My sample procedure with default \\\"modern\\\" formatting\",\";\",\"; :Arguments:\",\"; arg1: in, required, Boolean\",\"; My favorite argument\",\"; arg2: in, optional, Boolean\",\"; My second favorite argument\",\";\",\"; :Keywords:\",\"; KW1: in, required, Boolean\",\"; My favorite keyword\",\"; KW2: in, optional, Boolean\",\"; My second favorite keyword\",\";\",\";-\",\"pro mypro_modern, arg1, arg2, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2, hidden\",\"\",\" ;+ reference to our super cool and awesome plot\",\" a = plot(/test)\",\"\",\" ; sample if statement\",\" if !true then begin\",\" print, 42\",\" endif else begin\",\" print, 84\",\" endelse\",\"\",\" ; sample for loop\",\" foreach val, var, key do begin\",\"\",\" endforeach\",\"\",\" ; sample ENVI routine\",\" e = envi()\",\" r = ENVIRaster(metadata = meta) ; formatting matches docs\",\"\",\"end\"],\"config\":{\"autoDoc\":true,\"style\":{\"keywords\":\"lower\"}}}]}","auto-doc.structures.spec.ts":"{\"suiteName\":\"Generate structure docs\",\"fileName\":\"auto-doc.structures.spec.ts\",\"tests\":[{\"name\":\"to automatically add them\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"to do nothing without a class/structure definition routine\",\"code\":[\"pro pro4\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"add missing properties and sort alphabetically with bad at the end\",\"code\":[\";+\",\"; :MyStruct:\",\"; propFake: any\",\"; Placeholder docs for argument or keyword\",\"; prop2: any\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"with no properties\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.structures.2.spec.ts":"{\"suiteName\":\"Generate structure docs\",\"fileName\":\"auto-doc.structures.2.spec.ts\",\"tests\":[{\"name\":\"and verify spacing for empty structures\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {struct1}\",\"\",\" !null = {struct2}\",\"\",\" !null = {struct3, prop: 'socool'}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","format.after-main.spec.ts":"{\"suiteName\":\"Keep tokens after main level programs\",\"fileName\":\"format.after-main.spec.ts\",\"tests\":[{\"name\":\"example 1\",\"code\":[\"compile_opt idl2\",\"\",\"a = 5\",\"end\",\"; comment\",\"b = 17\"]}]}","format.after-line-continuation.spec.ts":"{\"suiteName\":\"Keep tokens after line continuations\",\"fileName\":\"format.after-line-continuation.spec.ts\",\"tests\":[{\"name\":\"example 1\",\"code\":[\"\",\"compile_opt idl2\",\"; thing\",\"a = $ something bad ;\",\" 5\",\"end\"]}]}","format.arrays.1.spec.ts":"{\"suiteName\":\"Verify array formatting\",\"fileName\":\"format.arrays.1.spec.ts\",\"tests\":[{\"name\":\"basic formatting\",\"code\":[\"compile_opt idl2\",\"\",\"a = [1,2,3,4,5]\",\"end\"]},{\"name\":\"line continuation 1\",\"code\":[\"compile_opt idl2\",\"\",\"a = [ $\",\" 1, $\",\" 2,$\",\" 3, $\",\" 4, $\",\" 5 $\",\"]\",\"end\"]},{\"name\":\"indexing and properties\",\"code\":[\"compile_opt idl2\",\"\",\"for xx = 0, numRows-1 do begin\",\"xRows[xx].Index = xCobs[xx].Index\",\"xRows[xx].Name = xCobs[xx].Name\",\"xRows[xx].Label = xCobs[xx].Label\",\"xRows[xx].SRS_Name = xCobs[xx].SRS_Name\",\"xRows[xx].Pos1 = xCobs[xx].Pos1\",\"xRows[xx].Dims1 = xCobs[xx].Dims1\",\"xRows[xx].Pos2 = xCobs[xx].Pos2\",\"xRows[xx].Dims2 = xCobs[xx].Dims2\",\"xRows[xx].Tm_Pos1 = xCobs[xx].Tm_Pos1\",\"xRows[xx].Tm_Pos2 = xCobs[xx].Tm_Pos2\",\"endfor\",\"\",\"end\"]},{\"name\":\"array indexing spacing\",\"code\":[\"overlaps.LOWER[sIdx] = ptr_new(segs[tSub[0] : tSub[2], tSub[3]])\"]},{\"name\":\"brackets for access (via overload)\",\"code\":[\"meta['band names'] = 'Awesome Label Regions'\"]},{\"name\":\"array after comma as argument\",\"code\":[\"compile_opt idl2\",\"\",\" inputValidator, hash( $\",\"'buffer', ['number', 'required'])\",\"\",\"end\"]}]}","format.assignment.1.spec.ts":"{\"suiteName\":\"Verify assignment formatting\",\"fileName\":\"format.assignment.1.spec.ts\",\"tests\":[{\"name\":\"multi-multi line assignment with operators looking correct\",\"code\":[\"compile_opt idl2\",\"\",\"a = 1 + $\",\" 2+ $\",\" 3 + $\",\" 4+ $\",\" 5\",\"end\"]}]}","format.comments.1.spec.ts":"{\"suiteName\":\"Verify comment\",\"fileName\":\"format.comments.1.spec.ts\",\"tests\":[{\"name\":\"all flavors of comments\",\"code\":[\"a = 42 ; comment OK\",\" ;; comment bad, now fixed \",\"; TODO: something super crazy \",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"limit formatting for routine comments\",\"code\":[\";+\",\"; My procedure\",\";\",\";; Preserve spacing in routine docs\",\" ; fix left alignment though\",\"; And trim the right side of the comment blocks \",\"; :Args:\",\"; var1: in, required, unknown\",\"; My favorite thing\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, var2, KW1=kw1, KW2=kw2\",\" compile_opt idl2\",\" if !true then begin\",\" print, 'yes'\",\" endif\",\"end\"]},{\"name\":\"add placeholder case for variable docs\",\"code\":[\" compile_opt idl2\",\"\",\" ;+ comment for variable\",\" ; leave indent formatting alone for now\",\" ;- stopped here\",\" a = 'something'\",\"end\"]},{\"name\":\" do not trim string before comment after line continuation\",\"code\":[\"compile_opt idl2\",\" ; left align\",\" a = 5 ; trim\",\"MESSAGE, $ ; keep my space!\",\"'baaaad'\",\"end\",\"\"]}]}","format.executive-commands.1.spec.ts":"{\"suiteName\":\"Executive command formatting\",\"fileName\":\"format.executive-commands.1.spec.ts\",\"tests\":[{\"name\":\"works without main end\",\"code\":[\"compile_opt idl2\",\"\",\".run something\",\" .compile myfile.pro \",\" .reset \",\"\"]}]}","format.line-separators.1.spec.ts":"{\"suiteName\":\"Line separator formatting\",\"fileName\":\"format.line-separators.1.spec.ts\",\"tests\":[{\"name\":\"always remove line separators, never allow them\",\"code\":[\"\",\"\",\"compile_opt idl2\",\"\",\"if !true then begin & a = b & b = c & c = d & endif\",\"\",\"end\",\"\"]}]}","format.line-separators.2.spec.ts":"{\"suiteName\":\"Line separators (&)\",\"fileName\":\"format.line-separators.2.spec.ts\",\"tests\":[{\"name\":\"Another example from docs\",\"code\":[\"compile_opt idl2\",\"\",\"if rtol lt ftol then begin ;Done?\",\"t = y[0] & y[0] = y[ilo] & y[ilo] = t ;Sort so fcn min is 0th elem\",\"t = p[*,ilo] & p[*,ilo] = p[*,0] & p[*,0] = t\",\"return, t ;params for fcn min\",\"endif\",\"\",\"end\"]}]}","format.new-lines.1.spec.ts":"{\"suiteName\":\"Verify new lines\",\"fileName\":\"format.new-lines.1.spec.ts\",\"tests\":[{\"name\":\"cannot have more than one empty line\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"\",\"\",\"return\",\"\",\"\",\"end\"]}]}","format.python.1.spec.ts":"{\"suiteName\":\"Format python code\",\"fileName\":\"format.python.1.spec.ts\",\"tests\":[{\"name\":\"for consistent spacing\",\"code\":[\"compile_opt idl2\",\"\",\">>>from idlpy import *\",\">>> arr = IDL.randomu(None, 10000)\",\">>> spec = IDL.fft_powerspectrum(arr, 0.1)\",\"end\",\"\"]}]}","format.respect-errors.1.spec.ts":"{\"suiteName\":\"Verify we do not format when we have bad syntax errors\",\"fileName\":\"format.respect-errors.1.spec.ts\",\"tests\":[{\"name\":\"unclosed tokens are ignored\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3 \",\" compile_opt idl2 \",\" \",\" a = myfunc(\",\"end \"]},{\"name\":\"unclosed main level is ignored\",\"code\":[\" compile_opt idl2 \",\" \",\"a = 5 \"]}]}","format.routines.1.spec.ts":"{\"suiteName\":\"Verify we format routines\",\"fileName\":\"format.routines.1.spec.ts\",\"tests\":[{\"name\":\"formats basic routine\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"formats basic method\",\"code\":[\"function myclass::mymethod, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"return, 1\",\"\",\"end\"]}]}","format.snap.1.spec.ts":"{\"suiteName\":\"Verify snapping branches to remove leading and trailing spaces\",\"fileName\":\"format.snap.1.spec.ts\",\"tests\":[{\"name\":\"all snap cases\",\"code\":[\"function test, a, $\",\" b\",\"\",\" compile_opt idl2\",\"\",\" wait, 0.5\",\"\",\" return, 1\",\"end\",\"\",\"function test::class, a, $\",\" b\",\"\",\" compile_opt idl2\",\"\",\" wait, 0.5\",\"\",\" return, 1\",\"end\",\"\",\"pro test::class, a, $\",\" b\",\"\",\" compile_opt idl2\",\"\",\" wait, 0.5\",\"\",\"end\",\"\",\"pro test, a, $\",\" b\",\"\",\" compile_opt idl2\",\"\",\" wait, 0.5\",\"\",\" if !true then begin\",\"\",\" print, 5\",\"\",\" print, 6\",\" \",\" endif\",\"\",\" switch (!true) of\",\"\",\" (42 eq 42): begin\",\"\",\" end\",\"\",\" else: begin\",\"\",\" ; do nothing\",\"\",\" end\",\"\",\" endswitch\",\"\",\"end\",\"\",\"\",\"compile_opt idl2\",\"\",\"print, 5\",\"\",\"wait, 2\",\"\",\"test\",\"\",\"print, 'Finished'\",\"\",\"end\"]}]}","format.trimming.1.spec.ts":"{\"suiteName\":\"Verify trimming lines\",\"fileName\":\"format.trimming.1.spec.ts\",\"tests\":[{\"name\":\"all lines should be trimmed from the right\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3 \",\" compile_opt idl2 \",\" \",\"end \"]}]}","style.control.spec.ts":"{\"suiteName\":\"Control statement styling\",\"fileName\":\"style.control.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" continue\",\" break\",\" forward_function\",\" common block, var1, var2, etc\",\" goto, myjump\",\" myjump:\",\"end\",\"\",\"function myfuncfunc\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\"compile_opt idl2\",\"\",\"; for loop\",\"for i=0,100,3 do begin\",\"\",\"endfor\",\"\",\"; foreach loop\",\"foreach val, var, key, do begin\",\"\",\"endforeach\",\"\",\"; while loop\",\"while !true do begin\",\"\",\"endwhile\",\"\",\"; repeat loop\",\"repeat print, !true until !false\",\"\",\"; switch statement\",\"switch !true of\",\" else: ; something\",\"endswitch\",\"\",\"; case statement\",\"case !true of\",\" else: ; something\",\"endcase\",\"\",\"; if statement\",\"if !true then begin\",\"\",\"endif else begin\",\"\",\"endelse\",\"\",\"; structure inheritance\",\"mystruct = {myname, INHerits plot}\",\"\",\"; executive command\",\".reset\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"control\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" continue\",\" break\",\" forward_function\",\" common block, var1, var2, etc\",\" goto, myjump\",\" myjump:\",\"end\",\"\",\"function myfuncfunc\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\"compile_opt idl2\",\"\",\"; for loop\",\"for i=0,100,3 do begin\",\"\",\"endfor\",\"\",\"; foreach loop\",\"foreach val, var, key, do begin\",\"\",\"endforeach\",\"\",\"; while loop\",\"while !true do begin\",\"\",\"endwhile\",\"\",\"; repeat loop\",\"repeat print, !true until !false\",\"\",\"; switch statement\",\"switch !true of\",\" else: ; something\",\"endswitch\",\"\",\"; case statement\",\"case !true of\",\" else: ; something\",\"endcase\",\"\",\"; if statement\",\"if !true then begin\",\"\",\"endif else begin\",\"\",\"endelse\",\"\",\"; structure inheritance\",\"mystruct = {myname, INHerits plot}\",\"\",\"; executive command\",\".reset\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"control\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" continue\",\" break\",\" forward_function\",\" common block, var1, var2, etc\",\" goto, myjump\",\" myjump:\",\"end\",\"\",\"function myfuncfunc\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\"compile_opt idl2\",\"\",\"; for loop\",\"for i=0,100,3 do begin\",\"\",\"endfor\",\"\",\"; foreach loop\",\"foreach val, var, key, do begin\",\"\",\"endforeach\",\"\",\"; while loop\",\"while !true do begin\",\"\",\"endwhile\",\"\",\"; repeat loop\",\"repeat print, !true until !false\",\"\",\"; switch statement\",\"switch !true of\",\" else: ; something\",\"endswitch\",\"\",\"; case statement\",\"case !true of\",\" else: ; something\",\"endcase\",\"\",\"; if statement\",\"if !true then begin\",\"\",\"endif else begin\",\"\",\"endelse\",\"\",\"; structure inheritance\",\"mystruct = {myname, INHerits plot}\",\"\",\"; executive command\",\".reset\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"control\":\"none\"}}}]}","style.internal-routines.spec.ts":"{\"suiteName\":\"Style internal routines\",\"fileName\":\"style.internal-routines.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" Return\",\"end\",\"\",\"compile_opt idl2\",\"\",\"PRINT\",\"Openr\",\"\",\"p = PLOT()\",\"\",\"r = enviraster()\",\"\",\"o = idlneturl()\",\"\",\"s = IDLFFSHAPE()\",\"\",\"!null = STRTOK('something')\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"match\"}}},{\"name\":\"using no format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" Return\",\"end\",\"\",\"compile_opt idl2\",\"\",\"PRINT\",\"Openr\",\"\",\"p = PLOT()\",\"\",\"r = enviraster()\",\"\",\"o = idlneturl()\",\"\",\"s = IDLFFSHAPE()\",\"\",\"!null = STRTOK('something')\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"none\"}}}]}","style.user-routines.spec.ts":"{\"suiteName\":\"Style user routines\",\"fileName\":\"style.user-routines.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"pro test_things\",\" compile_opt idl2\",\"end\",\"\",\"function test_THINGS\",\" compile_opt idl2\",\" return, 42\",\"end\",\"\",\"compile_opt idl2\",\"\",\"TEST_THINGS\",\"!null = test_things()\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"match\"}}},{\"name\":\"using no format\",\"code\":[\"pro test_things\",\" compile_opt idl2\",\"end\",\"\",\"function test_THINGS\",\" compile_opt idl2\",\" return, 42\",\"end\",\"\",\"compile_opt idl2\",\"\",\"TEST_THINGS\",\"!null = test_things()\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"none\"}}}]}","style.keywords.1.spec.ts":"{\"suiteName\":\"Verify keywords\",\"fileName\":\"style.keywords.1.spec.ts\",\"tests\":[{\"name\":\"basic formatting\",\"code\":[\"compile_opt idl2\",\"\",\"a = myfunc(KW1=kw2, /KW3)\",\"end\"]},{\"name\":\"with line continuation\",\"code\":[\"compile_opt idl2\",\"\",\"Graphic, name, arg1, arg2, $\",\"/AUTO_CROSSHAIR, COLOR=color, LINESTYLE=linestyle, $\",\"SYMBOL=SYMBOL, THICK=thick, LAYOUT=layout, TEST=test, _EXTRA=ex, $\",\"GRAPHIC=graphic\",\"\",\"end\"]},{\"name\":\"solo keyword\",\"code\":[\"compile_opt idl2\",\"\",\"a = myfunc(KW1=kw2)\",\"end\"]},{\"name\":\"solo binary keyword\",\"code\":[\"compile_opt idl2\",\"\",\"a = myfunc(/KW2)\",\"end\"]},{\"name\":\"preserve other children after keyword when we format\",\"code\":[\"compile_opt idl2\",\"tvcrs,x,y,/dev $ ;Restore cursor\",\" kw=2\",\"\",\"end\"]}]}","style.methods.spec.ts":"{\"suiteName\":\"Method styling\",\"fileName\":\"style.methods.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\" compile_opt idl2\",\"\",\"a = myclass . mymethod()\",\"myclass . mymethod\",\"a = myclass -> mymethod()\",\"myclass -> mymethod\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"methods\":\"dot\"}}},{\"name\":\"using dated format\",\"code\":[\" compile_opt idl2\",\"\",\"a = myclass . mymethod()\",\"myclass . mymethod\",\"a = myclass -> mymethod()\",\"myclass -> mymethod\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"methods\":\"arrow\"}}},{\"name\":\"using no format\",\"code\":[\" compile_opt idl2\",\"\",\"a = myclass . mymethod()\",\"myclass . mymethod\",\"a = myclass -> mymethod()\",\"myclass -> mymethod\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"methods\":\"none\"}}}]}","style.methods-call.spec.ts":"{\"suiteName\":\"Method styling\",\"fileName\":\"style.methods-call.spec.ts\",\"tests\":[{\"name\":\"match\",\"code\":[\"function myclass::MYMETHOD\",\"compile_opt idl2\",\"\",\"!null = self.myMethod()\",\"\",\"return, 1\",\"end\",\"\",\"pro myclass::MYMETHOD\",\"compile_opt idl2\",\"\",\"self.myMethod\",\"end\",\"\",\"pro auto_doc_example\",\"compile_opt idl2\",\"\",\"p = IDLgrSurface()\",\"!null = p.getFullIdentifier()\",\"p.SETVERTEXATTRIBUTEDATA\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"match\"}}},{\"name\":\"none\",\"code\":[\"function myclass::MYMETHOD\",\"compile_opt idl2\",\"\",\"!null = self.myMethod()\",\"\",\"return, 1\",\"end\",\"\",\"pro myclass::MYMETHOD\",\"compile_opt idl2\",\"\",\"self.myMethod\",\"end\",\"\",\"pro auto_doc_example\",\"compile_opt idl2\",\"\",\"p = IDLgrSurface()\",\"!null = p.getFullIdentifier()\",\"p.SETVERTEXATTRIBUTEDATA\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"none\"}}}]}","style.prompts.spec.ts":"{\"suiteName\":\"Prompt styling\",\"fileName\":\"style.prompts.spec.ts\",\"tests\":[{\"name\":\"format ENVI and IDL\",\"code\":[\"\",\"\",\"compile_opt idl2\",\"\",\"idl> print, 17\",\"\",\" envi>a = 5 + 6\",\"\",\"end\",\"\"]}]}","style.numbers.spec.ts":"{\"suiteName\":\"Number styling\",\"fileName\":\"style.numbers.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 45Ll\",\"\",\"a = \\\"101010\\\"bll\",\"\",\"a = \\\"777\\\"oS\",\"\",\"a = \\\"fFf\\\"xlL\",\"\",\"a = '101010'bll\",\"\",\"a = '777'oS\",\"\",\"a = 'fFf'xlL\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"numbers\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 45Ll\",\"\",\"a = \\\"101010\\\"bll\",\"\",\"a = \\\"777\\\"oS\",\"\",\"a = \\\"fFf\\\"xlL\",\"\",\"a = '101010'bll\",\"\",\"a = '777'oS\",\"\",\"a = 'fFf'xlL\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"numbers\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 45Ll\",\"\",\"a = \\\"101010\\\"bll\",\"\",\"a = \\\"777\\\"oS\",\"\",\"a = \\\"fFf\\\"xlL\",\"\",\"a = '101010'bll\",\"\",\"a = '777'oS\",\"\",\"a = 'fFf'xlL\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"numbers\":\"none\"}}}]}","style.hex.spec.ts":"{\"suiteName\":\"Hex number styling\",\"fileName\":\"style.hex.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0XaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"hex\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0XaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"hex\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0XaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"hex\":\"none\"}}}]}","style.octal.spec.ts":"{\"suiteName\":\"Octal number styling\",\"fileName\":\"style.octal.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0OaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"octal\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0OaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"octal\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0OaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"octal\":\"none\"}}}]}","style.binary.spec.ts":"{\"suiteName\":\"Binary number styling\",\"fileName\":\"style.binary.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0BaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"binary\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0BaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"binary\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0BaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"binary\":\"none\"}}}]}","style.properties.spec.ts":"{\"suiteName\":\"Property styling\",\"fileName\":\"style.properties.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = myvar.myPROP\",\"b = {SomeThing:'cool'}\",\"!null = b.SomeThing\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"properties\":\"match\"}}},{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = myvar.myPROP\",\"b = {SomeThing:'cool'}\",\"!null = b.SomeThing\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"properties\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = myvar.myPROP\",\"b = {SomeThing:'cool'}\",\"!null = b.SomeThing\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"properties\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = myvar.myPROP\",\"b = {SomeThing:'cool'}\",\"!null = b.SomeThing\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"properties\":\"none\"}}}]}","style.variables.1.spec.ts":"{\"suiteName\":\"Verify variable styling\",\"fileName\":\"style.variables.1.spec.ts\",\"tests\":[{\"name\":\"in procedures with modern formatting\",\"code\":[\"pro test_things, a, someTHING, c, KW1 = kw11\",\" compile_opt idl2\",\" A = something + C + keyword_set(KW11)\",\" taSK = ENVITask('Something')\",\" TASK = !null\",\" !null = enVi.openRaster()\",\" !null = enviTask.parameter()\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"match\"}}},{\"name\":\"in procedures with no formatting\",\"code\":[\"pro test_things, a, someTHING, c, KW1 = kw11\",\" compile_opt idl2\",\" A = something + C + keyword_set(KW11)\",\" taSK = ENVITask('Something')\",\" TASK = !null\",\" !null = enVi.openRaster()\",\" !null = enviTask.parameter()\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"none\"}}},{\"name\":\"in functions with modern formatting\",\"code\":[\"function test_things, a, someTHING, c, KW1 = kw11\",\" compile_opt idl2\",\" A = something + C + keyword_set(KW11)\",\" taSK = ENVITask('Something')\",\" TASK = !null\",\" !null = enVi.openRaster()\",\" !null = enviTask.parameter()\",\" return, task\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"match\"}}},{\"name\":\"in functions with no formatting\",\"code\":[\"function test_things, a, someTHING, c, KW1 = kw11\",\" compile_opt idl2\",\" A = something + C + keyword_set(KW11)\",\" taSK = ENVITask('Something')\",\" TASK = !null\",\" !null = enVi.openRaster()\",\" !null = enviTask.parameter()\",\" return, task\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"none\"}}},{\"name\":\"in main level with modern formatting\",\"code\":[\"compile_opt idl2\",\"A = something + C + keyword_set(KW11)\",\"taSK = ENVITask('Something')\",\"TASK = !null\",\"!null = enVi.openRaster()\",\"!null = enviTask.parameter()\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"match\"}}},{\"name\":\"in main level with no formatting\",\"code\":[\"compile_opt idl2\",\"A = something + C + keyword_set(KW11)\",\"taSK = ENVITask('Something')\",\"TASK = !null\",\"!null = enVi.openRaster()\",\"!null = enviTask.parameter()\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"none\"}}}]}","style.system-variables.spec.ts":"{\"suiteName\":\"System variable styling\",\"fileName\":\"style.system-variables.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = !SYSTEM_variable\",\"\",\"b = {!CPu, hw_vector: 0l, vector_enable: 0l, hw_ncpu: 0l,$\",\" tpool_nthreads: 0l, tpool_min_elts: 0l, tpool_max_elts: 0l}\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"systemVariables\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = !SYSTEM_variable\",\"\",\"b = {!CPu, hw_vector: 0l, vector_enable: 0l, hw_ncpu: 0l,$\",\" tpool_nthreads: 0l, tpool_min_elts: 0l, tpool_max_elts: 0l}\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"systemVariables\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = !SYSTEM_variable\",\"\",\"b = {!CPu, hw_vector: 0l, vector_enable: 0l, hw_ncpu: 0l,$\",\" tpool_nthreads: 0l, tpool_min_elts: 0l, tpool_max_elts: 0l}\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"systemVariables\":\"none\"}}}]}","format.indent.1.spec.ts":"{\"suiteName\":\"Verify adjusting indent adjusts spacing\",\"fileName\":\"format.indent.1.spec.ts\",\"tests\":[{\"name\":\"set indent to 3\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\"\",\" ; double quote\",\" a = \\\"something\\\"\",\"\",\" ; double quote with single quote\",\" a = \\\"'\\\"\",\"\",\" ; escaped double quote\",\" a = \\\"escaped\\\"\\\"formatting\\\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"tabWidth\":3,\"style\":{\"quotes\":\"single\"}}}]}","lib-examples.1.spec.ts":"{\"suiteName\":\"Verify code snippets from the lib folder\",\"fileName\":\"lib-examples.1.spec.ts\",\"tests\":[{\"name\":\"cw_ogc_wcs_cap.pro 1\",\"code\":[\"compile_opt idl2\",\"subsel = make_array(2, numRows, /byte) ; an array to hold the unique values\",\"subsel[0,0] = sel[*,1]\",\"lastRow = sel[1,0]\",\"ri = 1\",\"\",\";filter out all the rows that repeat\",\"for i=1, cnt-1 do begin\",\" if (lastRow ne sel[1,i]) then begin\",\" sel[0,i] = 1\",\" subsel[*,ri] = sel[*,i]\",\" lastRow = sel[1,i]\",\" ri++\",\" endif\",\"endfor\",\"\",\"end\"]},{\"name\":\"cw_ogc_wcs_cap.pro 2\",\"code\":[\"\",\"if ((*pstate).mouseState eq 1) then begin\",\"\",\" if (totCOBs gt rows) then begin\",\" if ((*pstate).scrollUp eq 0) then begin ; scroll down\",\" if ((*pstate).cobIndex lt totCOBs) then begin\",\"\",\"\",\" (*pstate).cobIndex = (*pstate).cobIndex + (*pstate).pageScrlInc\",\"\",\" idx = (*pstate).cobIndex\",\" skip = idx-rows\",\" if (skip gt (totCOBs - rows)) then begin\",\" skip = totCOBs - rows\",\" ;(*pstate).cobIndex = totCOBs-rows\",\" (*pstate).cobIndex = totCOBs\",\" endif\",\"\",\" res = (*pstate).owcs->GetCoverageOfferingBriefs(index=skip, number=rows)\",\" cw_ogc_wcs_cap_display_cap_table, ev, res\",\"\",\" endif\",\" endif else begin ; scroll up\",\" if ((*pstate).cobIndex gt rows) then begin\",\"\",\"\",\" (*pstate).cobIndex = (*pstate).cobIndex - (*pstate).pageScrlInc\",\"\",\" idx = (*pstate).cobIndex\",\" skip = idx-rows\",\"\",\" if (skip lt 0) then begin\",\" skip = 0\",\" (*pstate).cobIndex = rows\",\" endif\",\"\",\" res = (*pstate).owcs->GetCoverageOfferingBriefs(index=skip, number=rows)\",\" cw_ogc_wcs_cap_display_cap_table, ev, res\",\"\",\" endif\",\" endelse\",\" endif\",\"endif\",\"\",\"end\"]}]}","lib-examples.2.spec.ts":"{\"suiteName\":\"Lib examples 2\",\"fileName\":\"lib-examples.2.spec.ts\",\"tests\":[{\"name\":\"dist.pro\",\"code\":[\"function dist,n,m ;Return a rectangular array in which each pixel = euclidian\",\" ;distance from the origin.\",\"compile_opt idl2\",\"\",\"on_error,2 ;Return to caller if an error occurs\",\"\",\"n1 = n[0]\",\"m1 = (n_elements(m) le 0) ? n1 : m[0]\",\"x=findgen(n1) ;Make a row\",\"x = (x < (n1-x)) ^ 2 ;column squares\",\"\",\"a = FLTARR(n1,m1,/NOZERO) ;Make array\",\"\",\"for i=0L, m1/2 do begin ;Row loop\",\" y = sqrt(x + i^2.) ;Euclidian distance\",\" a[0,i] = y ;Insert the row\",\" if i ne 0 then a[0, m1-i] = y ;Symmetrical\",\"endfor\",\"return,a\",\"end\"]}]}","style.logic-case.1.spec.ts":"{\"suiteName\":\"Verify we style case\",\"fileName\":\"style.logic-case.1.spec.ts\",\"tests\":[{\"name\":\"formats messy case\",\"code\":[\"CASE x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\" 2 $\",\" : $\",\" PRINT, 'one' + func()\",\" ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDCASE\",\"end\"]},{\"name\":\"formats nested case\",\"code\":[\"CASE x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" CASE x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDCASE\",\"END\",\"ENDCASE\",\"end\"]},{\"name\":\"Properly format indents for case without line continuation\",\"code\":[\"compile_opt idl2\",\" ; determine how to proceed\",\" case !true of\",\" ; only have positive values\",\" negative eq !null: begin\",\" ranges[*, i] = [0, positive]\",\" end\",\"\",\" ; only have negative values\",\" positive eq !null: begin\",\" ranges[*, i] = [-negative, 0]\",\" end\",\"\",\" ; have positive and negative values\",\" else: begin\",\" ; get our bounds\",\" maxVal = negative > positive\",\"\",\" ; populate range\",\" ranges[*, i] = [-maxVal, maxVal]\",\" end\",\" endcase\",\"end\"]},{\"name\":\"removes spaces in logical default\",\"code\":[\"compile_opt idl2\",\"case N_PARAMS() of\",\"else : ; remove my space to the left after \\\"else\\\"\",\"endcase\",\"end\"]},{\"name\":\"properly formats this case/switch style\",\"code\":[\"compile_opt idl2\",\"\",\"; Just determine what to do and register.\",\"case 1 of\",\"\",\" keyword_set(visualization): $\",\" oSystem->RegisterVisualization, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(annotation): $\",\" oSystem->RegisterAnnotation, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(user_interface): $\",\"oSystem->RegisterUserInterface, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(ui_panel): $\",\"oSystem->RegisterUIPanel, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(ui_service): $\",\"oSystem->RegisterUIService, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(file_reader): $\",\"oSystem->RegisterFileReader, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(file_writer): $\",\"oSystem->RegisterFileWriter, strName, strClassName, _EXTRA = _extra\",\"\",\"else: $\",\"oSystem->RegisterTool, strName, strClassName, _EXTRA = _extra\",\"\",\"endcase\",\"end\"]}]}","style.logic-if-then.1.spec.ts":"{\"suiteName\":\"Verify we style if-then\",\"fileName\":\"style.logic-if-then.1.spec.ts\",\"tests\":[{\"name\":\"complex scenarios for if-then-else\",\"code\":[\" COMPILE_OPT idl2\",\"\",\" IF (n_elements(useDicomexIn) EQ 1) THEN $\",\" useDicomex = keyword_set(useDicomexIn) $\",\" ELSE $\",\" useDicomex = 1\",\"\",\" if !true then print, 'true' else print, 'false'\",\"\",\" IF (n_elements(useDicomexIn) EQ 1) $\",\"THEN $\",\" useDicomex = keyword_set(useDicomexIn) $\",\" ELSE $\",\" useDicomex = 1\",\"\",\" if !true then begin\",\"print, 'no'\",\" endif else begin\",\" b = 42\",\" endelse\",\"\",\"end\"]},{\"name\":\"keep on indenting with line continuations\",\"code\":[\"compile_opt idl2\",\"; when in paren, not as pretty\",\"if (!true $\",\" ) then $\",\"imageFFT = FFT(image, -1)\",\"\",\";;outside of paren, looks much nicer as long as enclosed\",\"if (!true)$\",\" then $\",\"imageFFT = FFT(image, -1)\",\"\",\"a = 5\",\"end\"]},{\"name\":\"complex indentation for if statement\",\"code\":[\"compile_opt idl2\",\"if ((imageSz.N_DIMENSIONS ne 2) || $\",\"((imageSz.TYPE ne 6) && (imageSz.TYPE ne 9)) || $\",\" MAX(imageSz.DIMENSIONS[0 : 1] ne imageDims[0] * 2)) then begin\",\" ; Double the image size and pad with zeros\",\" bigImage = dblarr(imageDims[0] * 2, imageDims[1] * 2)\",\" bigImage[0 : imageDims[0] - 1, 0 : imageDims[1] - 1] = image\",\" imageFFT = FFT(bigImage, -1)\",\" imageNElts = N_ELEMENTS(bigImage)\",\" endif\",\"end\"]},{\"name\":\"very complex if statement for regression test\",\"code\":[\"compile_opt idl2\",\"\",\" ;; Check to see if texture map was passed in as 3 or 4 separate 2D\",\" ;; arrays. textureRed, textureGreen, and textureBlue must all\",\" ;; be 2D arrays of the same size and type and textureImage must\",\" ;; not be set.\",\" IF keyword_set(textureRed) && keyword_set(textureGreen) && $\",\" keyword_set(textureBlue) && ~keyword_set(textureImage) && $\",\" (size(reform(textureRed),/n_dimensions) EQ 2) && $\",\" (size(reform(textureGreen),/n_dimensions) EQ 2) && $\",\" (size(reform(textureBlue),/n_dimensions) EQ 2) && $\",\" ( ((textmap_x=(size(reform(textureRed),/dimensions))[0])) EQ $\",\" (size(reform(textureGreen),/dimensions))[0] ) && $\",\" ( textmap_x EQ (size(reform(textureBlue),/dimensions))[0] ) && $\",\" ( ((textmap_y=(size(reform(textureRed),/dimensions))[1])) EQ $\",\" (size(reform(textureGreen),/dimensions))[1] ) && $\",\" ( textmap_y EQ (size(reform(textureBlue),/dimensions))[1] ) && $\",\" ( ((textmap_type=(size(reform(textureRed),/type))[0])) EQ $\",\" (size(reform(textureGreen),/type))[0] ) && $\",\" ( textmap_type EQ (size(reform(textureBlue),/type))[0] ) && $\",\" ( where(textmap_type EQ [0l,6,7,8,9,10,11]) EQ -1 ) THEN BEGIN\",\" ;; textureAlpha, if set, must match TEXTURE_* in size and type\",\" IF keyword_set(textureAlpha) && $\",\" (size(reform(textureAlpha),/n_dimensions) EQ 2) && $\",\" ( textmap_x EQ (size(reform(textureAlpha),/dimensions))[0]) && $\",\" ( textmap_y EQ (size(reform(textureAlpha),/dimensions))[1]) && $\",\" ( textmap_type EQ (size(reform(textureAlpha),/type))[0]) $\",\" THEN BEGIN\",\" textData = make_array(4,textmap_x,textmap_y,type=textmap_type)\",\" textData[0,*,*] = textureRed\",\" textData[1,*,*] = textureGreen\",\" textData[2,*,*] = textureBlue\",\" textData[3,*,*] = textureAlpha\",\" ENDIF ELSE BEGIN\",\" textData = make_array(3,textmap_x,textmap_y,type=textmap_type)\",\" textData[0,*,*] = textureRed\",\" textData[1,*,*] = textureGreen\",\" textData[2,*,*] = textureBlue\",\" ENDELSE\",\" oTextMap = obj_new('idlitDataIDLArray3d', textData, $\",\" NAME='TEXTURE')\",\" oParmSet->add, oTextMap, PARAMETER_NAME= \\\"TEXTURE\\\"\",\" ENDIF\",\"\",\"end\"]}]}","style.logic-switch.1.spec.ts":"{\"suiteName\":\"Verify we style switch\",\"fileName\":\"style.logic-switch.1.spec.ts\",\"tests\":[{\"name\":\"formats messy switch\",\"code\":[\"SWITCH x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\" 2 $\",\" : $\",\" PRINT, 'one' + func()\",\" ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDCASE\",\"end\"]},{\"name\":\"formats nested switch\",\"code\":[\"SWITCH x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" switch x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDCASE\",\"END\",\"ENDCASE\",\"end\"]}]}","style.logic-ternary.1.spec.ts":"{\"suiteName\":\"Verify we style ternary operators well\",\"fileName\":\"style.logic-ternary.1.spec.ts\",\"tests\":[{\"name\":\"simple case with spacing\",\"code\":[\"nPrint = (nTiles lt 100) ? 1:ceil(nTiles / 100.0)\"]},{\"name\":\"Case to preserve spacing before else\",\"code\":[\"oWorld = OBJ_VALID(oLayer) ? oLayer->GetWorld(): OBJ_NEW()\"]}]}","style.methods.1.spec.ts":"{\"suiteName\":\"Verify style for methods\",\"fileName\":\"style.methods.1.spec.ts\",\"tests\":[{\"name\":\"remove excess spaces\",\"code\":[\" compile_opt idl2\",\"\",\"a = myclass . mymethod()\",\"myclass . mymethod\",\"a = myclass -> mymethod()\",\"myclass -> mymethod\",\"\",\"end\"]}]}","style.operators.1.spec.ts":"{\"suiteName\":\"Verify operators\",\"fileName\":\"style.operators.1.spec.ts\",\"tests\":[{\"name\":\"pointers\",\"code\":[\"compile_opt idl2\",\"\",\"; complex pointers\",\"(*pstate).coDesCovIdArr[(*pstate).coDesCovIdArrIdx++] = ogc_wcs_descov(ev.top, (*pstate).owcs, covNames, '')\",\"\",\"end\"]},{\"name\":\"pointers\",\"code\":[\"compile_opt idl2\",\"\",\"*ptr = 42\",\"end\"]},{\"name\":\"operators that should not have spaces\",\"code\":[\"compile_opt idl2\",\"\",\"a++\",\"b--\",\"++c\",\"--d\",\"a += 6\",\"y -= 42\",\"m = --6\",\"n = ++4\",\"end\"]},{\"name\":\"handle tilde\",\"code\":[\"if ~keyword_set(difference_raster_uri) then difference_raster_uri = e.GetTemporaryFilename()\"]},{\"name\":\"pointer dereference and multiplication\",\"code\":[\"compile_opt idl2\",\"a = 5*10\",\"(*ptr).prop = 5\",\"b = *ptr\",\"segsUpper.Add, * overlaps.LOWER[mapXY[0], mapXY[1] - 1], /EXTRACT\",\"end\"]},{\"name\":\"remove spaces before operators where we do not need then\",\"code\":[\" compile_opt idl2\",\"\",\" a = - 1\",\" mypro, - 1\",\"\",\" ; create a struture to store information about our tile overlaps\",\" overlaps = { $\",\" IDX_X: - 0l $\",\" }\",\"deltas = ranges[1, *]-ranges[0, *]\",\"idxMin = [0 : - 2]\",\"end\"]},{\"name\":\"preserve spacing here\",\"code\":[\"a = ['Anomaly Detection: ' + task.MEAN_CALCULATION_METHOD]\"]},{\"name\":\"preserve spacing here too\",\"code\":[\"cs = !dpi *[0d : num_period - 1]\"]},{\"name\":\"operators by paren get properly ignored for trimming\",\"code\":[\"compile_opt idl2\",\" if (and filtMask and igMask) then filters = 'Image Files'\",\" if (eq filtMask and igMask) then filters = 'Image Files'\",\" if (ge filtMask and igMask) then filters = 'Image Files'\",\" if (gt filtMask and igMask) then filters = 'Image Files'\",\" if (le filtMask and igMask) then filters = 'Image Files'\",\" if (lt filtMask and igMask) then filters = 'Image Files'\",\" if (mod filtMask and igMask) then filters = 'Image Files'\",\" if (ne filtMask and igMask) then filters = 'Image Files'\",\" if (not filtMask and igMask) then filters = 'Image Files'\",\" if (or filtMask and igMask) then filters = 'Image Files'\",\" if (xor filtMask and igMask) then filters = 'Image Files'\",\"end\"]}]}","style.quotes-double.1.spec.ts":"{\"suiteName\":\"Verify double quote styling\",\"fileName\":\"style.quotes-double.1.spec.ts\",\"tests\":[{\"name\":\"convert double to single quote\",\"code\":[\" compile_opt idl2\",\"\",\" ; double quote\",\" a = \\\"something\\\"\",\"\",\" ; double quote with single quote\",\" a = \\\"'\\\"\",\"\",\" ; escaped double quote\",\" a = \\\"escaped\\\"\\\"formatting\\\"\",\"\",\" ; number strings\",\" a = \\\"010101\\\"b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"single\"}}},{\"name\":\"keep formatting when double quotes is preference\",\"code\":[\" compile_opt idl2\",\"\",\" ; double quote\",\" a = \\\"something\\\"\",\"\",\" ; double quote with single quote\",\" a = '\\\"'\",\"\",\" ; escaped double quote\",\" a = \\\"escaped\\\"\\\"formatting\\\"\",\"\",\" ; number strings\",\" a = \\\"010101\\\"b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"double\"}}}]}","style.quotes-none.1.spec.ts":"{\"suiteName\":\"Verify no formatting of quotes\",\"fileName\":\"style.quotes-none.1.spec.ts\",\"tests\":[{\"name\":\"preserve all quotes\",\"code\":[\"compile_opt idl2\",\"\",\"message, 'Each dimension must be greater than 1.\\\"'\",\"\",\"a = \\\"5\\\"\",\"\",\"a = 'fourty two'\",\"\",\"; for chris and doug\",\"a = '1'\",\"\",\"\",\" ; number strings\",\" a = \\\"010101\\\"b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"none\"}}}]}","style.quotes-nested.1.spec.ts":"{\"suiteName\":\"Verify double quote parsing\",\"fileName\":\"style.quotes-nested.1.spec.ts\",\"tests\":[{\"name\":\"preserve nested double quote when we use single\",\"code\":[\"compile_opt idl2\",\"\",\"message, 'Each dimension must be greater than 1.\\\"'\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"single\"}}},{\"name\":\"preserve nested single quote when we use double\",\"code\":[\"compile_opt idl2\",\"\",\"message, \\\"Each dimension must be greater than 1.'\\\"\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"double\"}}}]}","style.quotes-single.1.spec.ts":"{\"suiteName\":\"Verify single quote parsing\",\"fileName\":\"style.quotes-single.1.spec.ts\",\"tests\":[{\"name\":\"convert single to double quote\",\"code\":[\" compile_opt idl2\",\"\",\" ; single quote\",\" a = 'something'\",\"\",\" ; double quote with single quote\",\" a = '\\\"'\",\"\",\" ; escaped single quote\",\" a = 'escaped''formatting'\",\"\",\" ; number strings\",\" a = '010101'b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"double\"}}},{\"name\":\"keep formatting when single quotes is preference\",\"code\":[\" compile_opt idl2\",\"\",\" ; single quote\",\" a = 'something'\",\"\",\" ; double quote with single quote\",\" a = \\\"'\\\"\",\"\",\" ; escaped single quote\",\" a = 'escaped''formatting'\",\"\",\" ; number strings\",\" a = '010101'b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"single\"}}}]}","style.string-literal.1.spec.ts":"{\"suiteName\":\"Verify string literal styling\",\"fileName\":\"style.string-literal.1.spec.ts\",\"tests\":[{\"name\":\"simple\",\"code\":[\" compile_opt idl2 \",\"a = `my string with${expression}`\",\"b = `something ${5 + 6*12}`\",\" c = ` preserve as string`\",\";preserve interior spacing\",\"a = `with ${expression()} else`\",\" \",\"end \"]},{\"name\":\"multi-line\",\"code\":[\"compile_opt idl2\",\"; thing\",\"a = ` first\",\" second\",\" third\",\"`\",\"end\"]}]}","style.structures.1.spec.ts":"{\"suiteName\":\"Verify structures\",\"fileName\":\"style.structures.1.spec.ts\",\"tests\":[{\"name\":\"simple\",\"code\":[\" compile_opt idl2 \",\"fourty2 = { mystruct }\",\" \",\"end \"]},{\"name\":\"structure\",\"code\":[\"pro folderwatch__define\",\" compile_opt idl2, hidden\",\" on_error, 2\",\"\",\" void = { $\",\" FOLDERWATCH, $\",\" inherits idl_object, $\",\" _folder: '', $\",\" _callback: '', $\",\" _userdata: ptr_new(), $\",\" _added: 0b, $\",\" _modified: 0b, $\",\" _removed: 0b, $\",\" _frequency: 0d, $\",\" _timerid: 0l, $\",\" _fileinfo: ptr_new(), $\",\" _recursive: 0b, $\",\" _active: 0b, $\",\" _incallback: 0b $\",\" }\",\"\",\"end\"]},{\"name\":\"structure with arrays\",\"code\":[\"pro folderwatch__define\",\" compile_opt idl2, hidden\",\" on_error, 2\",\"\",\" void = { $\",\" IDX_XY: [0l, 0l], $\",\" RIGHT_MEANS: ptrarr(mapDims) $\",\" }\",\"\",\"end\"]},{\"name\":\"structure with line continuations regression\",\"code\":[\" compile_opt idl2, hidden\",\"!null = {IDLNotebook, $\",\" _foo: 5}\",\"\",\" !null = $\",\" {IDLNotebook, $\",\" _foo: 5}\",\"\",\" !null = { $\",\" _foo: 5}\",\"\",\" !null = $\",\" { $\",\" _foo: 5}\",\"end\"]}]}","style.template-escape.spec.ts":"{\"suiteName\":\"Verify auto-fix/format of template escape characters\",\"fileName\":\"style.template-escape.spec.ts\",\"tests\":[{\"name\":\" only changes the last line with modern\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"end\"],\"config\":{\"style\":{\"hex\":\"lower\"}}},{\"name\":\" only changes the last line with dated\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"end\"],\"config\":{\"style\":{\"hex\":\"upper\"}}},{\"name\":\" only changes the last line with none\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"end\"],\"config\":{\"style\":{\"hex\":\"none\"}}}]}"},"auto-task-assembler-tests":{"envitask.keywords1.spec.ts":"{\"suiteName\":\"Verify keyword formatting for ENVITasks\",\"fileName\":\"envitask.keywords1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"input_raster\\\",\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"output_raster_uri\\\",\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"output_raster\\\",\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"INPUT_RASTER\\\",\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_RASTER_URI\\\",\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_RASTER\\\",\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"INPUT_RASTER\\\",\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"output_RASTER_uri\\\",\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_RASTER\\\",\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"none\"}}}]}","envitask.parameters1.spec.ts":"{\"suiteName\":\"Verify parameter formatting for ENVI Tasks\",\"fileName\":\"envitask.parameters1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_RASTER_URI\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_RASTER\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster \\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" output_raster_uri \\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" OUTPUT_RASTER \\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"none\"}}}]}","envitask.direction1.spec.ts":"{\"suiteName\":\"Verify direction formatting for ENVI Tasks\",\"fileName\":\"envitask.direction1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\" ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"upper\"}}},{\"name\":\"lower case\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection \\\",\",\" \\\"description\\\": \\\" Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_RASTER_URI\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_RASTER\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"OUTPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster \\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" output_raster_uri \\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" OUTPUT_RASTER \\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"OUTPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"none\"}}}]}","envitask-legacy.keywords1.spec.ts":"{\"suiteName\":\"Verify keyword formatting for ENVI Task Legacy\",\"fileName\":\"envitask-legacy.keywords1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"input_raster\\\",\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"input_ecf_report_uri\\\",\",\" \\\"name\\\": \\\"input_ecf_report_uri\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"output_roi\\\",\",\" \\\"name\\\": \\\"output_roi\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"INPUT_RASTER\\\",\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"input_RASTER\\\",\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"none\"}}}]}","envitask-legacy.parameters1.spec.ts":"{\"suiteName\":\"Verify parameter formatting for ENVI Task Legacy\",\"fileName\":\"envitask-legacy.parameters1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"input_ecf_report_uri\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_roi\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\" mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\" ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\" This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\" ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_roi \\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"none\"}}}]}","envitask-legacy.direction-and-req1.spec.ts":"{\"suiteName\":\"Verify direction formatting for ENVI Task Legacy\",\"fileName\":\"envitask-legacy.direction-and-req1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\" ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\" ,\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"OUTPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"OUTPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"none\"}}}]}","idltask.keywords1.spec.ts":"{\"suiteName\":\"Verify keyword formatting for IDL Tasks\",\"fileName\":\"idltask.keywords1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"s3_url\\\",\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"local_file\\\",\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"S3_URL\\\",\",\" \\\"name\\\": \\\"S3_URL\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"LOCAL_FILE\\\",\",\" \\\"name\\\": \\\"LOCAL_FILE\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"S3_url\\\",\",\" \\\"name\\\": \\\"S3_URL\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"local_FILE\\\",\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"none\"}}}]}","idltask.parameters1.spec.ts":"{\"suiteName\":\"Verify parameter formatting for IDL Tasks\",\"fileName\":\"idltask.parameters1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"S3_URL\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"LOCAL_FILE\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"S3_URL\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"none\"}}}]}","idltask.direction1.spec.ts":"{\"suiteName\":\"Verify direction formatting for IDL Tasks\",\"fileName\":\"idltask.direction1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"none\"}}}]}"},"auto-problem-fixing-tests":{"code.3.after-main.spec.ts":"{\"suiteName\":\"Verify tokens after main get removed on formatting\",\"fileName\":\"code.3.after-main.spec.ts\",\"tests\":[{\"name\":\"basic case\",\"code\":[\"compile_opt idl2\",\"a = $ ; comment\",\" 5\",\"end\",\"\",\"; bad\",\" worse = not 42\"]}]}","code.14.colon-in-func.spec.ts":"{\"suiteName\":\"Verify function to array for\",\"fileName\":\"code.14.colon-in-func.spec.ts\",\"tests\":[{\"name\":\"basic case\",\"code\":[\"compile_opt idl2\",\"coefs = coefs_spc(*, 0 : junk - 1)\",\"end\"]}]}","code.15.colon-in-func-method.spec.ts":"{\"suiteName\":\"Verify function method to array for\",\"fileName\":\"code.15.colon-in-func-method.spec.ts\",\"tests\":[{\"name\":\"basic case\",\"code\":[\"compile_opt idl2\",\"a = objOrStruct.var(0 : -1)\",\"end\"]}]}","code.20.return-vals-pro.spec.ts":"{\"suiteName\":\"Verify we remove excess args\",\"fileName\":\"code.20.return-vals-pro.spec.ts\",\"tests\":[{\"name\":\"for procedures\",\"code\":[\";+\",\";-\",\"pro myname\",\" compile_opt idl2\",\"\",\" ; comment\",\" return, 42\",\"\",\"end\"]},{\"name\":\"for procedure methods\",\"code\":[\";+\",\";-\",\"pro myclass::myname\",\" compile_opt idl2\",\"\",\" a = 5\",\" return, 42\",\"end\"]},{\"name\":\"for main level programs\",\"code\":[\"; main\",\"compile_opt idl2\",\"\",\"return, 42\",\"\",\"end\"]}]}","code.21.return-vals-func.spec.ts":"{\"suiteName\":\"Verify we remove excess args\",\"fileName\":\"code.21.return-vals-func.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myname\",\" compile_opt idl2\",\"\",\" ;comment\",\" ; comment\",\" return, !null, $\",\" 2, myfunc()\",\"end\"]},{\"name\":\"for function methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::myname\",\" compile_opt idl2\",\"\",\" a = 5\",\" return, !null, 2\",\"end\"]}]}","code.31.return-missing.spec.ts":"{\"suiteName\":\"Verify we add missing return statement\",\"fileName\":\"code.31.return-missing.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myname\",\" compile_opt idl2\",\"\",\" ;comment\",\"end\"]},{\"name\":\"for function methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::myname\",\" compile_opt idl2\",\"\",\" a = 5\",\"end\"]}]}","code.35.after-continuation.spec.ts":"{\"suiteName\":\"Verify tokens after line continuation get removed on formatting\",\"fileName\":\"code.35.after-continuation.spec.ts\",\"tests\":[{\"name\":\"basic case\",\"code\":[\"compile_opt idl2\",\"a = $ 5 * bad ; comment\",\" 5\",\"end\"]}]}","code.38.no-comp-opt.spec.ts":"{\"suiteName\":\"Verify we add compile opt idl2\",\"fileName\":\"code.38.no-comp-opt.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myfunc\",\"\",\" return, 1\",\"end\"]},{\"name\":\"for function methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::myfunc\",\"\",\" return, 1\",\"end\"]},{\"name\":\"for procedures\",\"code\":[\";+\",\";-\",\"pro mypro\",\"\",\"end\"]},{\"name\":\"for procedure methods\",\"code\":[\";+\",\";-\",\"pro myclass::mypro\",\"\",\"end\"]},{\"name\":\"for main case 1\",\"code\":[\"; comment\",\"\",\"end\"]},{\"name\":\"for main case 2\",\"code\":[\"a = 5\",\"\",\"end\"]},{\"name\":\"for main case 3\",\"code\":[\"\",\"; comment\",\"\",\"a = 42\",\"\",\"end\"]},{\"name\":\"for main case 4\",\"code\":[\"\",\"; comment\",\"\",\"a = 42\",\"\",\"end\"]},{\"name\":\"with args and keywords\",\"code\":[\"function myfunc,$\",\"a, b, $\",\"kw2 = kw2\",\"\",\" return, 1\",\"end\"]}]}","code.38.no-comp-opt.edge-cases.spec.ts":"{\"suiteName\":\"Verify we add compile opt idl2\",\"fileName\":\"code.38.no-comp-opt.edge-cases.spec.ts\",\"tests\":[{\"name\":\"for functions without names\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function\",\"\",\"end\"]},{\"name\":\"for procedures without names\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"pro\",\"\",\"end\"]}]}","code.38.no-comp-opt.notebooks.spec.ts":"{\"suiteName\":\"Verify we add compile opt idl2\",\"fileName\":\"code.38.no-comp-opt.notebooks.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myfunc\",\"\",\" return, 1\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for function methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::myfunc\",\"\",\" return, 1\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for procedures\",\"code\":[\";+\",\";-\",\"pro mypro\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for procedure methods\",\"code\":[\";+\",\";-\",\"pro myclass::mypro\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for main case 1\",\"code\":[\"; comment\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for main case 2\",\"code\":[\"a = 5\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for main case 3\",\"code\":[\"\",\"; comment\",\"\",\"a = 42\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for main case 4\",\"code\":[\"\",\"; comment\",\"\",\"a = 42\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"with args and keywords\",\"code\":[\"function myfunc,$\",\"a, b, $\",\"kw2 = kw2\",\"\",\" return, 1\",\"end\"],\"parseConfig\":{\"isNotebook\":true}}]}","code.76.init-method-pro.spec.ts":"{\"suiteName\":\"Verify we change procedure init methods to function methods\",\"fileName\":\"code.76.init-method-pro.spec.ts\",\"tests\":[{\"name\":\"without return statements\",\"code\":[\"PRO myclass2::init\",\" compile_opt idl2\",\"\",\"end\",\"\",\"\",\"pro myclass::init\",\" compile_opt idl2\",\"\",\" ; comment\",\"end\"]},{\"name\":\"with return statements\",\"code\":[\"pro myclass::init\",\" compile_opt idl2\",\"\",\" ; comment\",\" return, !null\",\"end\",\"\",\"PRO myclass2::init\",\" compile_opt idl2\",\" return\",\"end\",\"\",\"\",\"pro myclass::init\",\" compile_opt idl2\",\" return\",\"end\"]}]}","code.105.illegal-var-index.spec.ts":"{\"suiteName\":\"Verify we correctly fix brackets for indexing\",\"fileName\":\"code.105.illegal-var-index.spec.ts\",\"tests\":[{\"name\":\"for simple case\",\"code\":[\";+ my var\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt strictarr\",\"code\":[\"compile_opt strictarr\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl2\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl3\",\"code\":[\"compile_opt idl3\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]}]}"},"auto-global-problem-tests":{"duplicates.spec.ts":"{\"suiteName\":\"Correctly identify duplicate problems\",\"fileName\":\"duplicates.spec.ts\",\"tests\":[{\"name\":\"while adding and removing files\",\"workspace\":\"idl/test/global-problems\",\"actions\":[{\"action\":\"add\",\"file\":\"file1.pro\"},{\"action\":\"add\",\"file\":\"file2.pro\"},{\"action\":\"add\",\"file\":\"file3.pro\"},{\"action\":\"remove\",\"file\":\"file1.pro\"},{\"action\":\"remove\",\"file\":\"file2.pro\"}]}]}","no-duplicate-main.spec.ts":"{\"suiteName\":\"Correctly ignore main level programs as duplicates\",\"fileName\":\"no-duplicate-main.spec.ts\",\"tests\":[{\"name\":\"with multiple files in the same workspace\",\"workspace\":\"idl/test/global-main-problems\",\"actions\":[{\"action\":\"add\",\"file\":\"file1.pro\"},{\"action\":\"add\",\"file\":\"file2.pro\"}]}]}"},"auto-config-resolution-tests":{"resolution.spec.ts":"{\"suiteName\":\"Correctly identify parses and returns config files\",\"fileName\":\"resolution.spec.ts\",\"tests\":[{\"name\":\"based on their folders\",\"workspace\":\"idl/test/configs\",\"actions\":[{\"action\":\"add\",\"file\":\"subdir1/idl.json\"},{\"action\":\"add\",\"file\":\"subdir2/idl.json\"},{\"action\":\"add\",\"file\":\"subdir3/idl.json\"},{\"action\":\"get\",\"file\":\"subdir1/idl.pro\"},{\"action\":\"get\",\"file\":\"subdir2/idl.pro\"},{\"action\":\"get\",\"file\":\"subdir3/idl.pro\"}]}]}","bad-file.spec.ts":"{\"suiteName\":\"Parse invalid config files\",\"fileName\":\"bad-file.spec.ts\",\"tests\":[{\"name\":\"and load default config for bad file\",\"workspace\":\"idl/test/configs\",\"actions\":[{\"action\":\"add\",\"file\":\"subdir4/idl.json\"},{\"action\":\"get\",\"file\":\"subdir4/idl.pro\"}]}]}"},"auto-task-generation-tests":{"envi.basic.spec.ts":"{\"suiteName\":\"Make basic ENVI task\",\"fileName\":\"envi.basic.spec.ts\",\"tests\":[{\"name\":\"from PRO\",\"file\":\"idl/test/task-generation/envitasktest.pro\",\"type\":\"envi\"}]}","envi.failure1.spec.ts":"{\"suiteName\":\"Don't make ENVI Task\",\"fileName\":\"envi.failure1.spec.ts\",\"tests\":[{\"name\":\"because of missing PRO definition\",\"file\":\"idl/test/task-generation/empty_envi.pro\",\"type\":\"envi\"}]}","idl.basic.spec.ts":"{\"suiteName\":\"Make basic IDL task\",\"fileName\":\"idl.basic.spec.ts\",\"tests\":[{\"name\":\"from PRO\",\"file\":\"idl/test/task-generation/idltasktest.pro\",\"type\":\"idl\"}]}","idl.failure1.spec.ts":"{\"suiteName\":\"Don't make IDL Task\",\"fileName\":\"idl.failure1.spec.ts\",\"tests\":[{\"name\":\"because of missing PRO definition\",\"file\":\"idl/test/task-generation/empty_idl.pro\",\"type\":\"idl\"}]}"}}
\ No newline at end of file
+{"auto-token-tests":{"assignment.spec.ts":"{\"suiteName\":\"Validates assignment parsing\",\"fileName\":\"assignment.spec.ts\",\"tests\":[{\"name\":\"parses variable assignment\",\"code\":\"a = 5\"},{\"name\":\"parses system variable assignment\",\"code\":\"!null = 5\"},{\"name\":\"brackets with assignment\",\"code\":\"a[i] = b\"},{\"name\":\"parses variable assignment with line continuation\",\"code\":[\"z = $\",\" 5\"]},{\"name\":\"assignment with parentheses\",\"code\":\"(b) = 15\"},{\"name\":\"procedure after assignment in loop and keyword\",\"code\":\"for i=0, myFunc(a=42) do print, i\"}]}","blocks.spec.ts":"{\"suiteName\":\"Validates block parsing auto-closes\",\"fileName\":\"blocks.spec.ts\",\"tests\":[{\"name\":\"lib example from kruskal_wallis.pro\",\"code\":[\"\",\"if !true then $\",\"\",\"while !true DO BEGIN\",\" a = 42 \",\"ENDWHILE $\",\"\",\"ELSE stop = stop+1\",\"end\"]}]}","brackets.spec.ts":"{\"suiteName\":\"Validates bracket parsing\",\"fileName\":\"brackets.spec.ts\",\"tests\":[{\"name\":\"parses standalone brackets\",\"code\":\"[1 + 2]\"},{\"name\":\"parses standalone brackets with line continuations\",\"code\":[\"[1 + $\",\" 2]\"]},{\"name\":\"indexing and compound expression\",\"code\":\"array1[1 + 2] * (1 + 2)\"},{\"name\":\"brackets with assignment\",\"code\":\"_a[i] = 5 * b\"},{\"name\":\"brackets with compound assignment\",\"code\":\"_aA$[i] *= b\"}]}","colon.spec.ts":"{\"suiteName\":\"Validates colon parsing\",\"fileName\":\"colon.spec.ts\",\"tests\":[{\"name\":\"simple colon test\",\"code\":\"[:]\"},{\"name\":\"array indexing\",\"code\":\"a[0:I] = 42\"}]}","commas.spec.ts":"{\"suiteName\":\"Validates comma parsing (mostly covered elsewhere)\",\"fileName\":\"commas.spec.ts\",\"tests\":[{\"name\":\"don't find commas on their own\",\"code\":\",\"},{\"name\":\"find commas in function\",\"code\":\"f(,)\"},{\"name\":\"find commas in pro\",\"code\":\"p,\"}]}","comments.spec.ts":"{\"suiteName\":\"Validates comment parsing\",\"fileName\":\"comments.spec.ts\",\"tests\":[{\"name\":\"parses simple comments\",\"code\":\" ; something()\"},{\"name\":\"parses code with comments at the end\",\"code\":\"a = b() ; something()\"},{\"name\":\"parses simple comments with TODO\",\"code\":\" ; TODO: something()\"},{\"name\":\"parses code with comments at the end with TODO\",\"code\":\"a = b() ; TODO: something()\"},{\"name\":\"parses code with comments and line continuations\",\"code\":[\"a = $ ; TODO: something()\",\" b()\"]}]}","control.1.spec.ts":"{\"suiteName\":\"Validates control statement parsing\",\"fileName\":\"control.1.spec.ts\",\"tests\":[{\"name\":\"parses basic control statements\",\"code\":[\"break\",\"continue\",\"jump: a = func()\",\"jump: mypro, $\",\" 5\",\"jumpy17$: ;comment\"]},{\"name\":\"parses break in if statements\",\"code\":\"if !true then break\"},{\"name\":\"parses continue in if statements\",\"code\":\"if !true then continue\"},{\"name\":\"parses continue and break in loops\",\"code\":[\"for i=0,99 do begin\",\" continue\",\" break\",\"endfor\"]},{\"name\":\"parses jump in blocks\",\"code\":[\"for i=0,99 do begin\",\" jump:\",\"endfor\"]},{\"name\":\"parses compound control statements\",\"code\":[\"common, group, var1, var2, var3 ; comment\",\"compile_opt, idl2, $ ; line continuation\",\" hidden\",\"compile_opt\",\"forward_function, idl2, hidden\",\"goto, label\"]},{\"name\":\"goto in in statement\",\"code\":\"if not wild then goto, done else printf, outunit\"},{\"name\":\"statements end at line separator\",\"code\":\"GOTO, do_six & END\"}]}","executive-command.spec.ts":"{\"suiteName\":\"Validates executive command parsing\",\"fileName\":\"executive-command.spec.ts\",\"tests\":[{\"name\":\"simple 1\",\"code\":\".compile\"},{\"name\":\"simple 2\",\"code\":\".run myfile.pro\"},{\"name\":\"simple 3 start with spaces\",\"code\":\" .run myfile.pro\"},{\"name\":\"ignore methods\",\"code\":\"obj.method\"},{\"name\":\"ignore properties\",\"code\":\"!null = obj.method\"}]}","include.spec.ts":"{\"suiteName\":\"Validates include statements, but not correct location\",\"fileName\":\"include.spec.ts\",\"tests\":[{\"name\":\"basic test\",\"code\":\"@includeme\"},{\"name\":\"don't find in functions\",\"code\":\"a = myfunc(@bad)\"},{\"name\":\"find in loops\",\"code\":\"for i=0,99 do @very_wrong\"},{\"name\":\"don't find in expressions\",\"code\":\"a = @include_wrong + @way_bad\"},{\"name\":\"don't capture afterwards\",\"code\":\"@include.pro ; comment\"}]}","lambda.spec.ts":"{\"suiteName\":\"Validates lambda functions parsed as special token\",\"fileName\":\"lambda.spec.ts\",\"tests\":[{\"name\":\"correctly parse lambda functions\",\"code\":\"a = lambda(x:x+2)\"}]}","line-modifiers.spec.ts":"{\"suiteName\":\"Validates line modifier (separators)\",\"fileName\":\"line-modifiers.spec.ts\",\"tests\":[{\"name\":\"parses multi-line as single-line\",\"code\":[\"a = a + b() & proc & a.procMethod,1 & $\",\"a={struct}\"]},{\"name\":\"loops properly stop in line modifier\",\"code\":[\"proc & for i=0,99 do print, i & while !true do b = awesome() & foreach val, b, key do print, key, val & endedit\"]},{\"name\":\"line separators in case statement\",\"code\":[\"CASE typ OF\",\" 7: begin val = \\\"\\\" & cnt = 1 & endcase\",\" 8: val = tiff_sint(val, 0, len=cnt)\",\"ENDCASE\"]},{\"name\":\"verifies nested line continuations use basic token\",\"code\":\"scale=scale, $, $\"}]}","logic.if-then-else.1.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [1]\",\"fileName\":\"logic.if-then-else.1.spec.ts\",\"tests\":[{\"name\":\"parses basic if-then loop\",\"code\":\"if !true then print, 'yes'\"},{\"name\":\"parses basic if-then-else loop\",\"code\":\"if ~doIt then print, 'yes' else a = yellow()\"},{\"name\":\"parses basic if-then loop with line continuation 1\",\"code\":[\"if !true $\",\" then print, 'yes'\"]},{\"name\":\"parses basic if-then loop with line continuation 2\",\"code\":[\"if !true $\",\" then print $\",\" , 'yes'\"]},{\"name\":\"parses basic if-then-else loop with line continuation 1\",\"code\":[\"if !true then print, 'yes' $\",\" else print, 'no'\"]},{\"name\":\"parses basic if-then-else loop with line continuation 2\",\"code\":[\"if !true then print, 'yes' $\",\" else $\",\" print, 'no'\"]},{\"name\":\"nested if-then-else\",\"code\":\"if ~(myFunc(_a17$) * 2) then if !false then print, 'yes'\"}]}","logic.if-then-else.2.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [2]\",\"fileName\":\"logic.if-then-else.2.spec.ts\",\"tests\":[{\"name\":\"with blocks [1]\",\"code\":[\"if a++ then begin\",\" super = awesome()\",\"endif else print, 'else'\"]}]}","logic.if-then-else.3.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [3]\",\"fileName\":\"logic.if-then-else.3.spec.ts\",\"tests\":[{\"name\":\"example from IDL code [1]\",\"code\":\"if i ne 0 then a[0, m1-i] = y ;Symmetrical\"},{\"name\":\"example from IDL code [2]\",\"code\":[\"if (ISA(equation)) then begin\",\" graphic.SetProperty, EQUATION=equation\",\" arg1 = equation\",\" if (ISA(style)) then arg2 = style\",\"endif\"]},{\"name\":\"example from IDL code [3]\",\"code\":[\"IF (nms[i-1, j] && ~marked[i-1, j]) THEN $\",\" canny_follow, i-1, j, nms, marked\"]},{\"name\":\"example from IDL code [4]\",\"code\":[\"IF (max(step) && ~n_elements(stepflag)) THEN $\",\" suppMag = nmsupp_mask * mag\"]},{\"name\":\"example from IDL code [5]\",\"code\":[\"if (~Isa(hDefinition, 'Hash') || $\",\" ~hDefinition.HasKey('schema') || $\",\" ~(hDefinition['schema']).StartsWith('IDLColorGradientDefinition', /FOLD_CASE)) then begin\",\" message, 'File does not contain a valid color gradient definition.', /NONAME \",\"endif\"]}]}","logic.case.1.spec.ts":"{\"suiteName\":\"Validates case statement\",\"fileName\":\"logic.case.1.spec.ts\",\"tests\":[{\"name\":\"parses case loop with many syntaxes\",\"code\":[\"CASE x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\"ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDCASE\"]},{\"name\":\"nested case statement\",\"code\":[\"CASE x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" CASE x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDCASE\",\"END\",\"ENDCASE\"]}]}","logic.switch.1.spec.ts":"{\"suiteName\":\"Validates switch statement\",\"fileName\":\"logic.switch.1.spec.ts\",\"tests\":[{\"name\":\"parses switch loop with many syntaxes\",\"code\":[\"SWITCH x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\"ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDSWITCH\"]},{\"name\":\"nested switch statement\",\"code\":[\"SWITCH x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" SWITCH x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDSWITCH\",\"END\",\"ENDSWITCH\"]}]}","logic.ternary.1.spec.ts":"{\"suiteName\":\"Validates for ternary statement parsing\",\"fileName\":\"logic.ternary.1.spec.ts\",\"tests\":[{\"name\":\"simplest ternary statement\",\"code\":\"a = something ? 5 : 6\"},{\"name\":\"nested ternary statement grouped\",\"code\":\"a = !true ? (!false ? 7 : 8) : 6\"},{\"name\":\"nested ternary statement without grouping\",\"code\":\"mypro, something ? ~something ? 7 : 8 : 6, 2\"},{\"name\":\"ternary as argument\",\"code\":\"a = myfunc(something ? otherfunc() : !awesomesauce) + 3\"},{\"name\":\"operators end on ternary statements\",\"code\":\"a = 5*something ? 5- 4 : 6^3\"},{\"name\":\"multi-line ternary 1\",\"code\":[\"a = _myvar $\",\" ? 'jello' : \\\"jelly\\\"\"]},{\"name\":\"multi-line ternary 2\",\"code\":[\"a = myfunc( $\",\" a,b,c) ? b4d $\",\" : $\",\" s1nt4x3x4mple\"]},{\"name\":\"ternary works in braces as expected\",\"code\":[\"_17 = arr[!true ? 0 : -3: -1]\"]}]}","loops.for.spec.ts":"{\"suiteName\":\"Validates for loop parsing\",\"fileName\":\"loops.for.spec.ts\",\"tests\":[{\"name\":\"parses basic for loop\",\"code\":\"for i=0, 99 do print, i\"},{\"name\":\"parses basic for loop with increment\",\"code\":\"for i=0, 99, 2 do !null = myFunc(i)\"},{\"name\":\"parses basic for loop with line continuation\",\"code\":[\"for i=0, jj do $\",\" print, i\"]},{\"name\":\"parses basic for loop with block\",\"code\":[\"for i=0, 99 do begin\",\" !null = myFunc(i)\",\"endfor\"]},{\"name\":\"parses nested for loop\",\"code\":\"for i=0, 99 do for j=0, 99 do print, i + j\"}]}","loops.foreach.spec.ts":"{\"suiteName\":\"Validates foreach loop parsing\",\"fileName\":\"loops.foreach.spec.ts\",\"tests\":[{\"name\":\"parses basic foreach loop\",\"code\":\"foreach val, arr do print, i\"},{\"name\":\"parses basic foreach loop with key\",\"code\":\"foreach val, arr, idx do !null = myFunc(i)\"},{\"name\":\"parses basic foreach loop with line continuation\",\"code\":[\"foreach val, arr do $\",\" print, i\"]},{\"name\":\"parses basic foreach loop with block\",\"code\":[\"foreach val, arr do begin\",\" !null = myFunc(i)\",\"endforeach\"]},{\"name\":\"parses nested foreach loop\",\"code\":\"foreach val, arr do foreach val2, val do print, val2\"}]}","loops.repeat.spec.ts":"{\"suiteName\":\"Validates repeat loop parsing\",\"fileName\":\"loops.repeat.spec.ts\",\"tests\":[{\"name\":\"parses basic repeat loop\",\"code\":\"REPEAT A = A * 2 UNTIL A GT B\"},{\"name\":\"parses procedure in repeat loop\",\"code\":\"REPEAT PRINT, A UNTIL A GT B\"},{\"name\":\"parses basic repeat loop with line continuations\",\"code\":[\"REPEAT A = $\",\" A * 2 UNTIL $\",\" A GT B\"]},{\"name\":\"parses basic repeat loop with block\",\"code\":[\"REPEAT BEGIN\",\" A = A * 2\",\"ENDREP UNTIL A GT B\"]},{\"name\":\"correctly parses loops with if statements inside\",\"code\":[\"repeat if !true then break until !true\"]}]}","loops.while.spec.ts":"{\"suiteName\":\"Validates while loop parsing\",\"fileName\":\"loops.while.spec.ts\",\"tests\":[{\"name\":\"parses basic while loop\",\"code\":\"while !true do print, i\"},{\"name\":\"parses basic nested while loop\",\"code\":\"while !true do while !false do print, i\"},{\"name\":\"parses basic while loop with line continuation\",\"code\":[\"while !true do $\",\" print, $\",\" i\"]},{\"name\":\"parses basic while loop with block\",\"code\":[\"while (a eq 5) do begin\",\" !null = myFunc(i)\",\"endwhile\"]}]}","methods.functions.spec.ts":"{\"suiteName\":\"Validates function method parsing\",\"fileName\":\"methods.functions.spec.ts\",\"tests\":[{\"name\":\"parses function methods with dots\",\"code\":\"!NULL = a.myFunc(1)\"},{\"name\":\"parses function methods with arrows\",\"code\":\"!NULL = a->myFunc(1)\"},{\"name\":\"parses super function methods with dots\",\"code\":\"a.super::myfunc(1)\"},{\"name\":\"parses super function methods with arrows\",\"code\":\"a->super::myfunc(a)\"},{\"name\":\"parses function methods with dots and line continuation\",\"code\":[\"!NULL = a.myFunc( $\",\" 1)\"]},{\"name\":\"single-character function method\",\"code\":\"a.b()\"}]}","methods.procedures.spec.ts":"{\"suiteName\":\"Validates procedure method parsing\",\"fileName\":\"methods.procedures.spec.ts\",\"tests\":[{\"name\":\"parses procedure methods with dots\",\"code\":\"a.myProc, 1\"},{\"name\":\"parses procedure methods with arrows\",\"code\":\"a->myProc, a\"},{\"name\":\"parses super procedure methods with dots\",\"code\":\"a.super::myProc, 1\"},{\"name\":\"parses super procedure methods with arrows\",\"code\":\"a->super::myProc, a\"},{\"name\":\"parses procedure methods with dots and line continuations\",\"code\":[\"a.myProc, $\",\" 1\"]},{\"name\":\"procedure method from IDL lib\",\"code\":[\"((*state).markers).Add, CGRAD_NEW_MARKER(POSITION=marker['position'], $\",\" COLOR=color, $\",\" MIDDLE=marker['middle'])\"]},{\"name\":\"single-character procedure method\",\"code\":\"a.b\"}]}","numbers.spec.ts":"{\"suiteName\":\"Validates special cases for number parsing\",\"fileName\":\"numbers.spec.ts\",\"tests\":[{\"name\":\"correctly parse scientific notations\",\"code\":[\"a = -1e34\",\"a = -1e34i\",\"a = -1e34j\"]},{\"name\":\"correctly parse scientific notations with negatives 1\",\"code\":[\"a = 1e-34\",\"a = 1e-34i\",\"a = 1e-34j\"]},{\"name\":\"correctly parse scientific notations with negatives 2\",\"code\":[\"a = 1e-\",\"a = 1e-i\",\"a = 1e-j\"]},{\"name\":\"correctly parse hex notation\",\"code\":[\"a = 0x8FFF + 0x8Fub + 0x8FulL\",\"a = 0x8FFFI + 0x8FubI + 0x8FulLi\",\"a = 0x8FFFJ + 0x8Fubj + 0x8FulLJ\"]},{\"name\":\"correctly parse octal notation\",\"code\":[\"a = 0o8FFF + 0o8Fub + 0o8FulL\",\"a = 0o8FFFI + 0o8FubI + 0o8FulLi\",\"a = 0o8FFFJ + 0o8Fubj + 0o8FulLJ\"]},{\"name\":\"correctly parse binary notation\",\"code\":[\"a = 0b8FFF + 0b8Fub + 0b8FulL\",\"a = 0b8FFFI + 0b8FubI + 0b8FulLi\",\"a = 0b8FFFJ + 0b8Fubj + 0b8FulLJ\"]},{\"name\":\"correctly parse scientific notations with doubles\",\"code\":[\"a = -1d34\",\"a = -1d34i\",\"a = -1d34j\"]},{\"name\":\"correctly parse scientific notations with doubles with negatives 1\",\"code\":[\"a = 1d-34\",\"a = 1d-34i\",\"a = 1d-34j\"]},{\"name\":\"correctly parse scientific notations with doubles with negatives 2\",\"code\":[\"a = 1d-\",\"a = 1d-i\",\"a = 1d-j\"]},{\"name\":\"correctly parse new syntax for complex\",\"code\":[\"a = 1i\",\"a = 1j\"]},{\"name\":\"catch unfinished dot statement 1\",\"code\":\"a.\"},{\"name\":\"catch unfinished dot statement 2\",\"code\":\"a = b.\"},{\"name\":\"catch standalone dot\",\"code\":\"a = .\"},{\"name\":\"edge case scientific\",\"code\":\"a = .1e+12\"},{\"name\":\"solo dot\",\"code\":\".\"}]}","number-string.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36 + \\\"45\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36b + \\\"45ull\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'b\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'x\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'o\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"b\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"x\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"o\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XS\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XS\"}]}","number-string.complex-i.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.complex-i.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36i + \\\"45i\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36bi + \\\"45ulli\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'bi\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'xi\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'oi\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"bi\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"xi\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"oi\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XSi\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XSi\"}]}","number-string.complex-j.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.complex-j.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36j + \\\"45j\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36bj + \\\"45ullj\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'bj\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'xj\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'oj\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"bj\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"xj\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"oj\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XSj\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XSj\"}]}","operators.compound.spec.ts":"{\"suiteName\":\"Validates compound operator parsing\",\"fileName\":\"operators.compound.spec.ts\",\"tests\":[{\"name\":\"parses with line continuation\",\"code\":[\"z *= $\",\" 5\"]},{\"name\":\"does not recurse with \\\"||\\\" operator\",\"code\":\"a || b || c\"},{\"name\":\"does not recurse with \\\"or\\\" operator\",\"code\":\"a or b or c\"},{\"name\":\"captures all statements with \\\"&&\\\" operator\",\"code\":\"a && b && c\"},{\"name\":\"captures all statements with \\\"&&\\\" operator\",\"code\":\"a and b and c\"}]}","operators.spec.ts":"{\"suiteName\":\"Validates operator parsing\",\"fileName\":\"operators.spec.ts\",\"tests\":[{\"name\":\"close on braces\",\"code\":\"{1+2}\"},{\"name\":\"close on brackets\",\"code\":\"[1+2]\"},{\"name\":\"close on parentheses\",\"code\":\"(1+2)\"},{\"name\":\"close on commas\",\"code\":\"1+2,3+4\"},{\"name\":\"close on then and else\",\"code\":\"if 1+2 then a = 3+4 else a = 4^3\"},{\"name\":\"close on do in loops\",\"code\":\"for i=0, 99-1 do print, i\"},{\"name\":\"operators with line continuations\",\"code\":[\"zach + $ \",\"awesome\"]},{\"name\":\"operators end on \\\"of\\\"\",\"code\":[\"case n_params()-1 of\",\" 0: call_method, method_name, oObj[i], _extra=e\",\" 1: call_method, method_name, oObj[i], p1, _extra=e\",\"endcase\"]},{\"name\":\"operators end on arrow function\",\"code\":\"*(*pState).pTitle->SetProperty, color=[255, 255, 255]\"},{\"name\":\"operators end on procedure method\",\"code\":\"*pTitle.SetProperty, color=[255, 255, 255]\"},{\"name\":\"operators do not end on function method\",\"code\":\"*pTitle.SetProperty(color=[255, 255, 255])\"},{\"name\":\"operators do not end on function method\",\"code\":\"*pTitle->SetProperty(color=[255, 255, 255])\"},{\"name\":\"special token for increment\",\"code\":[\"++a\",\"a++\"]},{\"name\":\"special token for decrement\",\"code\":[\"--a\",\"a+--\"]},{\"name\":\"next to each other\",\"code\":\"a = b++ + 5\"}]}","parentheses.spec.ts":"{\"suiteName\":\"Validates parentheses parsing\",\"fileName\":\"parentheses.spec.ts\",\"tests\":[{\"name\":\"parses standalone parentheses\",\"code\":\"(1 + 2)\"},{\"name\":\"separate function from parentheses\",\"code\":\"myFunc(1 + 2) * (1 + 2)\"},{\"name\":\"parses standalone parentheses with line continuation\",\"code\":[\"(1 + $ \",\" 2)\"]}]}","prompts.spec.ts":"{\"suiteName\":\"Validates prompt parsing\",\"fileName\":\"prompts.spec.ts\",\"tests\":[{\"name\":\"parses IDL prompt\",\"code\":\"IDL> print, 42\"},{\"name\":\"parses ENVI prompt\",\"code\":\"ENVI> print, 17\"}]}","properties.spec.ts":"{\"suiteName\":\"Validates property parsing\",\"fileName\":\"properties.spec.ts\",\"tests\":[{\"name\":\"parses property assignment\",\"code\":\"a.thing = 5\"},{\"name\":\"parses property access\",\"code\":\"b = a.thing\"},{\"name\":\"parses property access with line continuation\",\"code\":[\"b = $\",\" a.thing\"]},{\"name\":\"parses nested property access\",\"code\":\"b = a.thing1.thing2\"},{\"name\":\"parses property access as arguments\",\"code\":\"myPro, a.thing, b.thing\"},{\"name\":\"property example from IDL lib\",\"code\":\"(*state).bottomSelection = lMarkers.Count()-1\"},{\"name\":\"structure property via indexing\",\"code\":\"a = b.(i)\"}]}","python.spec.ts":"{\"suiteName\":\"Validates Python code parsing\",\"fileName\":\"python.spec.ts\",\"tests\":[{\"name\":\"parses IDL prompt\",\"code\":\">>>import numpy as np\"}]}","quotes.spec.ts":"{\"suiteName\":\"Validates quote parsing\",\"fileName\":\"quotes.spec.ts\",\"tests\":[{\"name\":\"parses standalone single quotes\",\"code\":\"'myFunc(1 + 2)'\"},{\"name\":\"parses standalone double quotes\",\"code\":\"\\\"myFunc(1 + 2)\\\"\"},{\"name\":\"verify single quotes without closing\",\"code\":\"'string\"},{\"name\":\"verify double quotes without closing\",\"code\":\"\\\"string\"},{\"name\":\"confusing single quote\",\"code\":\"hDefinition['schema']).StartsWith('IDLColorGradientDefinition', /FOLD_CASE)\"},{\"name\":\"confusing double quote\",\"code\":\"hDefinition[\\\"schema\\\"]).StartsWith(\\\"IDLColorGradientDefinition\\\", /FOLD_CASE)\"},{\"name\":\"quotes end at important statements 1\",\"code\":[\"if \\\"bad-quote\\\"then \\\"bad-quote\\\"else\"]},{\"name\":\"quotes end at important statements 2\",\"code\":[\"case \\\"bad-quote\\\"of\"]},{\"name\":\"quotes end at important statements 3\",\"code\":[\"for \\\"bad-quote\\\"do\"]},{\"name\":\"quotes end at important statements 4\",\"code\":[\"repeat 'bad-quote'until\"]},{\"name\":\"quotes end at important statements 5\",\"code\":[\"if 'bad-quote'then 'bad-quote'else\"]},{\"name\":\"quotes end at important statements 6\",\"code\":[\"case 'bad-quote'of\"]},{\"name\":\"quotes end at important statements 7\",\"code\":[\"for 'bad-quote'do\"]},{\"name\":\"quotes end at important statements 8\",\"code\":[\"repeat 'bad-quote'until\"]},{\"name\":\"verifies quote vs number is correctly identified\",\"code\":[\"arr = [\\\"0.00000000\\\"]\"]}]}","quotes.escaped.spec.ts":"{\"suiteName\":\"Validates escaped quote parsing\",\"fileName\":\"quotes.escaped.spec.ts\",\"tests\":[{\"name\":\"simple single quote\",\"code\":\"'Resolve_Routine, ''%s'', Is_Function=%d'\"},{\"name\":\"simple double quote\",\"code\":\"\\\"Resolve_Routine, \\\"\\\"%s\\\"\\\", Is_Function=%d\\\"\"},{\"name\":\"complex single quote\",\"code\":\"'Resolve_Routine, ''%s'', Is_Function=%d''lots of''other''string'\"},{\"name\":\"complex double quote\",\"code\":\"\\\"Resolve_Routine, \\\"\\\"%s\\\"\\\", Is_Function=%d\\\"\\\"lots of\\\"\\\"other\\\"\\\"string\\\"\"}]}","quotes.edge-cases.spec.ts":"{\"suiteName\":\"Validates edge case quote parsing\",\"fileName\":\"quotes.edge-cases.spec.ts\",\"tests\":[{\"name\":\"for number-string like strings\",\"code\":\"a = \\\"5\\\"\"}]}","routines.functions.spec.ts":"{\"suiteName\":\"Validates function parsing\",\"fileName\":\"routines.functions.spec.ts\",\"tests\":[{\"name\":\"parses standalone functions\",\"code\":\"myFunc(1 + 2)\"},{\"name\":\"parses nested functions\",\"code\":\"myFunc(myFunc2(_y7$) + 2)\"},{\"name\":\"separate function from parentheses\",\"code\":\"myFunc(1 + 2) * (1 + 2)\"},{\"name\":\"parses standalone functions with line continuations\",\"code\":[\"myFunc(1 $\",\" + 2)\"]},{\"name\":\"single-character function\",\"code\":\"a()\"}]}","routines.keywords.spec.ts":"{\"suiteName\":\"Validates keyword parsing\",\"fileName\":\"routines.keywords.spec.ts\",\"tests\":[{\"name\":\"parses keyword assignment\",\"code\":\"myfunc(a = 5)\"},{\"name\":\"parses multiple keywords\",\"code\":\"_otherfunc(a = 5, _b=42)\"},{\"name\":\"parses multiple keywords with line continuation\",\"code\":[\"myfunc(a = 5, $\",\" _b=42)\"]},{\"name\":\"parses keyword assignment with line continuation\",\"code\":[\"myfunc(a $\",\" = 5)\"]},{\"name\":\"parses variable assignment\",\"code\":\"_y = _superFunction(a = 5)\"}]}","routines.procedures.spec.ts":"{\"suiteName\":\"Validates procedure parsing\",\"fileName\":\"routines.procedures.spec.ts\",\"tests\":[{\"name\":\"parses standalone procedures\",\"code\":\"myPro, 1 + 2\"},{\"name\":\"separate pro from variables\",\"code\":\"myPro, arg1, arg2\"},{\"name\":\"pro with line continuations\",\"code\":[\"myPro, $\",\" arg1, arg2\"]},{\"name\":\"pro in loop after arguments and function\",\"code\":\"for i=0, 2*5-jello(1) do print, i\"},{\"name\":\"single-character procedure\",\"code\":\"a\"}]}","routines.spacing.spec.ts":"{\"suiteName\":\"Validates routine spacing\",\"fileName\":\"routines.spacing.spec.ts\",\"tests\":[{\"name\":\"functions\",\"code\":\"myFunc (1 + 2)\"},{\"name\":\"procedures\",\"code\":\"mypro ,\"},{\"name\":\"function method (dots)\",\"code\":\"a . method ()\"},{\"name\":\"function method (arrow)\",\"code\":\"a -> method ()\"},{\"name\":\"procedure method 1 (dots)\",\"code\":\"a . method \"},{\"name\":\"procedure method 2 (dots)\",\"code\":\"a . method , \"},{\"name\":\"procedure method 1 (arrow)\",\"code\":\"a -> method \"},{\"name\":\"procedure method 2 (arrow)\",\"code\":\"a -> method , \"}]}","routines.definitions.1.spec.ts":"{\"suiteName\":\"Validates routine parsing\",\"fileName\":\"routines.definitions.1.spec.ts\",\"tests\":[{\"name\":\"verifies procedure with arguments and keywords\",\"code\":[\"PRO EndMagic, arg1, $ ; comment\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"END\"]},{\"name\":\"verifies functions with arguments and keywords\",\"code\":[\"function myfunc, arg1, $ ; comment\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"end\"]},{\"name\":\"verifies procedure method with arguments and keywords\",\"code\":[\"PRO myclass::mymethod, arg1, $ ; comment\",\" ; skip empty lines\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"END\"]},{\"name\":\"verifies function method with arguments and keywords\",\"code\":[\"function myfuncclass::mymethod, arg1, $ ; comment\",\"\",\" arg2, KW1 = $\",\"\",\" kw1, KW2 = kw2\",\"\",\"end\"]},{\"name\":\"verifies more than one routine\",\"code\":[\"Function f1\",\" return, 5\",\"end\",\"\",\"pro p1\",\" print, 42\",\"end\"]}]}","routines.definitions.2.spec.ts":"{\"suiteName\":\"Validates routine parsing\",\"fileName\":\"routines.definitions.2.spec.ts\",\"tests\":[{\"name\":\"verifies we only stop on \\\"end\\\"\",\"code\":[\"PRO EndMagic, Unit, Id\",\" PRINTF, Unit\",\"END\"]},{\"name\":\"verifies we parse names with \\\"!\\\"\",\"code\":[\"pro !sosobad,\",\"END\"]},{\"name\":\"verifies we parse method names with \\\"!\\\"\",\"code\":[\"pro !sosobad::method,\",\"END\"]},{\"name\":\"routines in a very bad single-line\",\"code\":\"FUNCTION VarName, Ptr & RETURN,'' & END\"}]}","string-literal.spec.ts":"{\"suiteName\":\"Verify string literal processing\",\"fileName\":\"string-literal.spec.ts\",\"tests\":[{\"name\":\"simple with substitution\",\"code\":\"a = `my string with ${expression + 5}`\"},{\"name\":\"simple without substitution\",\"code\":\"a = `my string without substitution`\"},{\"name\":\"properly capture nested literals\",\"code\":\"a = `start ${ `nested` } else`\"},{\"name\":\"complex nested case\",\"code\":\"a = `something ${func(a = b, `nested`, /kw) + 6*12} else ${5*5 + `something` + nested} some`\"},{\"name\":\"parse escaped backticks\",\"code\":\"a = `something \\\\` included `\"},{\"name\":\"preserve spacing when extracting tokens\",\"code\":\"a = ` first `\"},{\"name\":\"template literal string with formatting\",\"code\":\"a = `${1.234,\\\"%10.3f\\\"}`\"}]}","string-literal.multiline.spec.ts":"{\"suiteName\":\"Verify string literal processing with multi-line statements\",\"fileName\":\"string-literal.multiline.spec.ts\",\"tests\":[{\"name\":\"preserve spacing and handle multi-line string literals\",\"code\":[\"compile_opt idl2\",\"; thing\",\"a = ` first\",\" second\",\" third\",\"last`\",\"end\"]}]}","string-literal.escape.spec.ts":"{\"suiteName\":\"Verify string literal escape characters\",\"fileName\":\"string-literal.escape.spec.ts\",\"tests\":[{\"name\":\"for syntax highlighting\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"a = `\\\\a `\",\"end\"]}]}","structures.1.spec.ts":"{\"suiteName\":\"Validates structure parsing\",\"fileName\":\"structures.1.spec.ts\",\"tests\":[{\"name\":\"verifies simplest structure parsing\",\"code\":\"_z5$ = {thing}\"},{\"name\":\"verifies multi-line structure name parsing\",\"code\":[\"_17$ = { $\",\" thing}\"]},{\"name\":\"verifies simplest property parsing without structure name\",\"code\":\"_17$ = {thing:z}\"},{\"name\":\"verifies simplest property parsing without structure name and line continuation\",\"code\":[\"_17$ = { $\",\" thing:z}\"]},{\"name\":\"verifies simplest nested structure parsing\",\"code\":\"_z5$ = {thing1:{thing2:z}}\"},{\"name\":\"verifies structure with inheritance\",\"code\":\"_z5$ = {thing, inherits _jklol}\"},{\"name\":\"verifies all components in single-line\",\"code\":\"a17 = {_th1g, abc:def, b:5, c:f()}\"}]}","structures.2.spec.ts":"{\"suiteName\":\"Validates structure parsing\",\"fileName\":\"structures.2.spec.ts\",\"tests\":[{\"name\":\"verifies multiple structure names (even though wrong syntax)\",\"code\":\"a = {one,two,three,inherits thing, inherits other, prop:5} ; comment\"},{\"name\":\"verifies nested structures, line continuations, and comments\",\"code\":[\"_17$ = { $ ; something\",\" thing: {name, some:value}}\"]},{\"name\":\"verifies weird syntax for named structures\",\"code\":[\"new_event = {FILESEL_EVENT, parent, ev.top, 0L, $\",\"path+filename, 0L, theFilter}\"]},{\"name\":\"structure names with exclamation points\",\"code\":\"a = {!exciting}\"},{\"name\":\"structure names and then line continuation\",\"code\":\"void = {mlLabelingTool_GraphicOverlay $\"},{\"name\":\"inherits supports spaces\",\"code\":[\" void = {IDLitDataIDLArray2D, $\",\" inherits IDLitData}\"]}]}","unexpected.1.spec.ts":"{\"suiteName\":\"Validates unexpected closer parsing\",\"fileName\":\"unexpected.1.spec.ts\",\"tests\":[{\"name\":\"verifies we catch unexpected closers (other tests cover correctly catching real closers instead of these)\",\"code\":[\")\",\"]\",\"}\",\"endif\",\"endelse\",\"endfor\",\"endforeach\",\"endrep\",\"endwhile\",\"endswitch\",\"endcase\",\"end\"]}]}","unknown.spec.ts":"{\"suiteName\":\"Validates unknown token parsing\",\"fileName\":\"unknown.spec.ts\",\"tests\":[{\"name\":\"improper arrow function\",\"code\":\"sEvent.component-> $\"},{\"name\":\"text after comment\",\"code\":\"a = $ bad bad\"},{\"name\":\"unknown has right positioning with zero-width matches\",\"code\":\"scale=scale, $, $\"}]}"},"auto-textmate-tests":{"assignment.spec.ts":"{\"suiteName\":\"Validates assignment parsing\",\"fileName\":\"assignment.spec.ts\",\"tests\":[{\"name\":\"parses variable assignment\",\"code\":\"a = 5\"},{\"name\":\"parses system variable assignment\",\"code\":\"!null = 5\"},{\"name\":\"brackets with assignment\",\"code\":\"a[i] = b\"},{\"name\":\"parses variable assignment with line continuation\",\"code\":[\"z = $\",\" 5\"]},{\"name\":\"assignment with parentheses\",\"code\":\"(b) = 15\"},{\"name\":\"procedure after assignment in loop and keyword\",\"code\":\"for i=0, myFunc(a=42) do print, i\"}]}","blocks.spec.ts":"{\"suiteName\":\"Validates block parsing auto-closes\",\"fileName\":\"blocks.spec.ts\",\"tests\":[{\"name\":\"lib example from kruskal_wallis.pro\",\"code\":[\"\",\"if !true then $\",\"\",\"while !true DO BEGIN\",\" a = 42 \",\"ENDWHILE $\",\"\",\"ELSE stop = stop+1\",\"end\"]}]}","brackets.spec.ts":"{\"suiteName\":\"Validates bracket parsing\",\"fileName\":\"brackets.spec.ts\",\"tests\":[{\"name\":\"parses standalone brackets\",\"code\":\"[1 + 2]\"},{\"name\":\"parses standalone brackets with line continuations\",\"code\":[\"[1 + $\",\" 2]\"]},{\"name\":\"indexing and compound expression\",\"code\":\"array1[1 + 2] * (1 + 2)\"},{\"name\":\"brackets with assignment\",\"code\":\"_a[i] = 5 * b\"},{\"name\":\"brackets with compound assignment\",\"code\":\"_aA$[i] *= b\"}]}","colon.spec.ts":"{\"suiteName\":\"Validates colon parsing\",\"fileName\":\"colon.spec.ts\",\"tests\":[{\"name\":\"simple colon test\",\"code\":\"[:]\"},{\"name\":\"array indexing\",\"code\":\"a[0:I] = 42\"}]}","commas.spec.ts":"{\"suiteName\":\"Validates comma parsing (mostly covered elsewhere)\",\"fileName\":\"commas.spec.ts\",\"tests\":[{\"name\":\"don't find commas on their own\",\"code\":\",\"},{\"name\":\"find commas in function\",\"code\":\"f(,)\"},{\"name\":\"find commas in pro\",\"code\":\"p,\"}]}","comments.spec.ts":"{\"suiteName\":\"Validates comment parsing\",\"fileName\":\"comments.spec.ts\",\"tests\":[{\"name\":\"parses simple comments\",\"code\":\" ; something()\"},{\"name\":\"parses code with comments at the end\",\"code\":\"a = b() ; something()\"},{\"name\":\"parses simple comments with TODO\",\"code\":\" ; TODO: something()\"},{\"name\":\"parses code with comments at the end with TODO\",\"code\":\"a = b() ; TODO: something()\"},{\"name\":\"parses code with comments and line continuations\",\"code\":[\"a = $ ; TODO: something()\",\" b()\"]}]}","control.1.spec.ts":"{\"suiteName\":\"Validates control statement parsing\",\"fileName\":\"control.1.spec.ts\",\"tests\":[{\"name\":\"parses basic control statements\",\"code\":[\"break\",\"continue\",\"jump: a = func()\",\"jump: mypro, $\",\" 5\",\"jumpy17$: ;comment\"]},{\"name\":\"parses break in if statements\",\"code\":\"if !true then break\"},{\"name\":\"parses continue in if statements\",\"code\":\"if !true then continue\"},{\"name\":\"parses continue and break in loops\",\"code\":[\"for i=0,99 do begin\",\" continue\",\" break\",\"endfor\"]},{\"name\":\"parses jump in blocks\",\"code\":[\"for i=0,99 do begin\",\" jump:\",\"endfor\"]},{\"name\":\"parses compound control statements\",\"code\":[\"common, group, var1, var2, var3 ; comment\",\"compile_opt, idl2, $ ; line continuation\",\" hidden\",\"compile_opt\",\"forward_function, idl2, hidden\",\"goto, label\"]},{\"name\":\"goto in in statement\",\"code\":\"if not wild then goto, done else printf, outunit\"},{\"name\":\"statements end at line separator\",\"code\":\"GOTO, do_six & END\"}]}","executive-command.spec.ts":"{\"suiteName\":\"Validates executive command parsing\",\"fileName\":\"executive-command.spec.ts\",\"tests\":[{\"name\":\"simple 1\",\"code\":\".compile\"},{\"name\":\"simple 2\",\"code\":\".run myfile.pro\"},{\"name\":\"simple 3 start with spaces\",\"code\":\" .run myfile.pro\"},{\"name\":\"ignore methods\",\"code\":\"obj.method\"},{\"name\":\"ignore properties\",\"code\":\"!null = obj.method\"}]}","include.spec.ts":"{\"suiteName\":\"Validates include statements, but not correct location\",\"fileName\":\"include.spec.ts\",\"tests\":[{\"name\":\"basic test\",\"code\":\"@includeme\"},{\"name\":\"don't find in functions\",\"code\":\"a = myfunc(@bad)\"},{\"name\":\"find in loops\",\"code\":\"for i=0,99 do @very_wrong\"},{\"name\":\"don't find in expressions\",\"code\":\"a = @include_wrong + @way_bad\"},{\"name\":\"don't capture afterwards\",\"code\":\"@include.pro ; comment\"}]}","lambda.spec.ts":"{\"suiteName\":\"Validates lambda functions parsed as special token\",\"fileName\":\"lambda.spec.ts\",\"tests\":[{\"name\":\"correctly parse lambda functions\",\"code\":\"a = lambda(x:x+2)\"}]}","line-modifiers.spec.ts":"{\"suiteName\":\"Validates line modifier (separators)\",\"fileName\":\"line-modifiers.spec.ts\",\"tests\":[{\"name\":\"parses multi-line as single-line\",\"code\":[\"a = a + b() & proc & a.procMethod,1 & $\",\"a={struct}\"]},{\"name\":\"loops properly stop in line modifier\",\"code\":[\"proc & for i=0,99 do print, i & while !true do b = awesome() & foreach val, b, key do print, key, val & endedit\"]},{\"name\":\"line separators in case statement\",\"code\":[\"CASE typ OF\",\" 7: begin val = \\\"\\\" & cnt = 1 & endcase\",\" 8: val = tiff_sint(val, 0, len=cnt)\",\"ENDCASE\"]},{\"name\":\"verifies nested line continuations use basic token\",\"code\":\"scale=scale, $, $\"}]}","logic.if-then-else.1.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [1]\",\"fileName\":\"logic.if-then-else.1.spec.ts\",\"tests\":[{\"name\":\"parses basic if-then loop\",\"code\":\"if !true then print, 'yes'\"},{\"name\":\"parses basic if-then-else loop\",\"code\":\"if ~doIt then print, 'yes' else a = yellow()\"},{\"name\":\"parses basic if-then loop with line continuation 1\",\"code\":[\"if !true $\",\" then print, 'yes'\"]},{\"name\":\"parses basic if-then loop with line continuation 2\",\"code\":[\"if !true $\",\" then print $\",\" , 'yes'\"]},{\"name\":\"parses basic if-then-else loop with line continuation 1\",\"code\":[\"if !true then print, 'yes' $\",\" else print, 'no'\"]},{\"name\":\"parses basic if-then-else loop with line continuation 2\",\"code\":[\"if !true then print, 'yes' $\",\" else $\",\" print, 'no'\"]},{\"name\":\"nested if-then-else\",\"code\":\"if ~(myFunc(_a17$) * 2) then if !false then print, 'yes'\"}]}","logic.if-then-else.2.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [2]\",\"fileName\":\"logic.if-then-else.2.spec.ts\",\"tests\":[{\"name\":\"with blocks [1]\",\"code\":[\"if a++ then begin\",\" super = awesome()\",\"endif else print, 'else'\"]}]}","logic.if-then-else.3.spec.ts":"{\"suiteName\":\"Validates for if-then-else parsing [3]\",\"fileName\":\"logic.if-then-else.3.spec.ts\",\"tests\":[{\"name\":\"example from IDL code [1]\",\"code\":\"if i ne 0 then a[0, m1-i] = y ;Symmetrical\"},{\"name\":\"example from IDL code [2]\",\"code\":[\"if (ISA(equation)) then begin\",\" graphic.SetProperty, EQUATION=equation\",\" arg1 = equation\",\" if (ISA(style)) then arg2 = style\",\"endif\"]},{\"name\":\"example from IDL code [3]\",\"code\":[\"IF (nms[i-1, j] && ~marked[i-1, j]) THEN $\",\" canny_follow, i-1, j, nms, marked\"]},{\"name\":\"example from IDL code [4]\",\"code\":[\"IF (max(step) && ~n_elements(stepflag)) THEN $\",\" suppMag = nmsupp_mask * mag\"]},{\"name\":\"example from IDL code [5]\",\"code\":[\"if (~Isa(hDefinition, 'Hash') || $\",\" ~hDefinition.HasKey('schema') || $\",\" ~(hDefinition['schema']).StartsWith('IDLColorGradientDefinition', /FOLD_CASE)) then begin\",\" message, 'File does not contain a valid color gradient definition.', /NONAME \",\"endif\"]}]}","logic.case.1.spec.ts":"{\"suiteName\":\"Validates case statement\",\"fileName\":\"logic.case.1.spec.ts\",\"tests\":[{\"name\":\"parses case loop with many syntaxes\",\"code\":[\"CASE x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\"ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDCASE\"]},{\"name\":\"nested case statement\",\"code\":[\"CASE x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" CASE x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDCASE\",\"END\",\"ENDCASE\"]}]}","logic.switch.1.spec.ts":"{\"suiteName\":\"Validates switch statement\",\"fileName\":\"logic.switch.1.spec.ts\",\"tests\":[{\"name\":\"parses switch loop with many syntaxes\",\"code\":[\"SWITCH x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\"ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDSWITCH\"]},{\"name\":\"nested switch statement\",\"code\":[\"SWITCH x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" SWITCH x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDSWITCH\",\"END\",\"ENDSWITCH\"]}]}","logic.ternary.1.spec.ts":"{\"suiteName\":\"Validates for ternary statement parsing\",\"fileName\":\"logic.ternary.1.spec.ts\",\"tests\":[{\"name\":\"simplest ternary statement\",\"code\":\"a = something ? 5 : 6\"},{\"name\":\"nested ternary statement grouped\",\"code\":\"a = !true ? (!false ? 7 : 8) : 6\"},{\"name\":\"nested ternary statement without grouping\",\"code\":\"mypro, something ? ~something ? 7 : 8 : 6, 2\"},{\"name\":\"ternary as argument\",\"code\":\"a = myfunc(something ? otherfunc() : !awesomesauce) + 3\"},{\"name\":\"operators end on ternary statements\",\"code\":\"a = 5*something ? 5- 4 : 6^3\"},{\"name\":\"multi-line ternary 1\",\"code\":[\"a = _myvar $\",\" ? 'jello' : \\\"jelly\\\"\"]},{\"name\":\"multi-line ternary 2\",\"code\":[\"a = myfunc( $\",\" a,b,c) ? b4d $\",\" : $\",\" s1nt4x3x4mple\"]},{\"name\":\"ternary works in braces as expected\",\"code\":[\"_17 = arr[!true ? 0 : -3: -1]\"]}]}","loops.for.spec.ts":"{\"suiteName\":\"Validates for loop parsing\",\"fileName\":\"loops.for.spec.ts\",\"tests\":[{\"name\":\"parses basic for loop\",\"code\":\"for i=0, 99 do print, i\"},{\"name\":\"parses basic for loop with increment\",\"code\":\"for i=0, 99, 2 do !null = myFunc(i)\"},{\"name\":\"parses basic for loop with line continuation\",\"code\":[\"for i=0, jj do $\",\" print, i\"]},{\"name\":\"parses basic for loop with block\",\"code\":[\"for i=0, 99 do begin\",\" !null = myFunc(i)\",\"endfor\"]},{\"name\":\"parses nested for loop\",\"code\":\"for i=0, 99 do for j=0, 99 do print, i + j\"}]}","loops.foreach.spec.ts":"{\"suiteName\":\"Validates foreach loop parsing\",\"fileName\":\"loops.foreach.spec.ts\",\"tests\":[{\"name\":\"parses basic foreach loop\",\"code\":\"foreach val, arr do print, i\"},{\"name\":\"parses basic foreach loop with key\",\"code\":\"foreach val, arr, idx do !null = myFunc(i)\"},{\"name\":\"parses basic foreach loop with line continuation\",\"code\":[\"foreach val, arr do $\",\" print, i\"]},{\"name\":\"parses basic foreach loop with block\",\"code\":[\"foreach val, arr do begin\",\" !null = myFunc(i)\",\"endforeach\"]},{\"name\":\"parses nested foreach loop\",\"code\":\"foreach val, arr do foreach val2, val do print, val2\"}]}","loops.repeat.spec.ts":"{\"suiteName\":\"Validates repeat loop parsing\",\"fileName\":\"loops.repeat.spec.ts\",\"tests\":[{\"name\":\"parses basic repeat loop\",\"code\":\"REPEAT A = A * 2 UNTIL A GT B\"},{\"name\":\"parses procedure in repeat loop\",\"code\":\"REPEAT PRINT, A UNTIL A GT B\"},{\"name\":\"parses basic repeat loop with line continuations\",\"code\":[\"REPEAT A = $\",\" A * 2 UNTIL $\",\" A GT B\"]},{\"name\":\"parses basic repeat loop with block\",\"code\":[\"REPEAT BEGIN\",\" A = A * 2\",\"ENDREP UNTIL A GT B\"]},{\"name\":\"correctly parses loops with if statements inside\",\"code\":[\"repeat if !true then break until !true\"]}]}","loops.while.spec.ts":"{\"suiteName\":\"Validates while loop parsing\",\"fileName\":\"loops.while.spec.ts\",\"tests\":[{\"name\":\"parses basic while loop\",\"code\":\"while !true do print, i\"},{\"name\":\"parses basic nested while loop\",\"code\":\"while !true do while !false do print, i\"},{\"name\":\"parses basic while loop with line continuation\",\"code\":[\"while !true do $\",\" print, $\",\" i\"]},{\"name\":\"parses basic while loop with block\",\"code\":[\"while (a eq 5) do begin\",\" !null = myFunc(i)\",\"endwhile\"]}]}","methods.functions.spec.ts":"{\"suiteName\":\"Validates function method parsing\",\"fileName\":\"methods.functions.spec.ts\",\"tests\":[{\"name\":\"parses function methods with dots\",\"code\":\"!NULL = a.myFunc(1)\"},{\"name\":\"parses function methods with arrows\",\"code\":\"!NULL = a->myFunc(1)\"},{\"name\":\"parses super function methods with dots\",\"code\":\"a.super::myfunc(1)\"},{\"name\":\"parses super function methods with arrows\",\"code\":\"a->super::myfunc(a)\"},{\"name\":\"parses function methods with dots and line continuation\",\"code\":[\"!NULL = a.myFunc( $\",\" 1)\"]},{\"name\":\"single-character function method\",\"code\":\"a.b()\"}]}","methods.procedures.spec.ts":"{\"suiteName\":\"Validates procedure method parsing\",\"fileName\":\"methods.procedures.spec.ts\",\"tests\":[{\"name\":\"parses procedure methods with dots\",\"code\":\"a.myProc, 1\"},{\"name\":\"parses procedure methods with arrows\",\"code\":\"a->myProc, a\"},{\"name\":\"parses super procedure methods with dots\",\"code\":\"a.super::myProc, 1\"},{\"name\":\"parses super procedure methods with arrows\",\"code\":\"a->super::myProc, a\"},{\"name\":\"parses procedure methods with dots and line continuations\",\"code\":[\"a.myProc, $\",\" 1\"]},{\"name\":\"procedure method from IDL lib\",\"code\":[\"((*state).markers).Add, CGRAD_NEW_MARKER(POSITION=marker['position'], $\",\" COLOR=color, $\",\" MIDDLE=marker['middle'])\"]},{\"name\":\"single-character procedure method\",\"code\":\"a.b\"}]}","numbers.spec.ts":"{\"suiteName\":\"Validates special cases for number parsing\",\"fileName\":\"numbers.spec.ts\",\"tests\":[{\"name\":\"correctly parse scientific notations\",\"code\":[\"a = -1e34\",\"a = -1e34i\",\"a = -1e34j\"]},{\"name\":\"correctly parse scientific notations with negatives 1\",\"code\":[\"a = 1e-34\",\"a = 1e-34i\",\"a = 1e-34j\"]},{\"name\":\"correctly parse scientific notations with negatives 2\",\"code\":[\"a = 1e-\",\"a = 1e-i\",\"a = 1e-j\"]},{\"name\":\"correctly parse hex notation\",\"code\":[\"a = 0x8FFF + 0x8Fub + 0x8FulL\",\"a = 0x8FFFI + 0x8FubI + 0x8FulLi\",\"a = 0x8FFFJ + 0x8Fubj + 0x8FulLJ\"]},{\"name\":\"correctly parse octal notation\",\"code\":[\"a = 0o8FFF + 0o8Fub + 0o8FulL\",\"a = 0o8FFFI + 0o8FubI + 0o8FulLi\",\"a = 0o8FFFJ + 0o8Fubj + 0o8FulLJ\"]},{\"name\":\"correctly parse binary notation\",\"code\":[\"a = 0b8FFF + 0b8Fub + 0b8FulL\",\"a = 0b8FFFI + 0b8FubI + 0b8FulLi\",\"a = 0b8FFFJ + 0b8Fubj + 0b8FulLJ\"]},{\"name\":\"correctly parse scientific notations with doubles\",\"code\":[\"a = -1d34\",\"a = -1d34i\",\"a = -1d34j\"]},{\"name\":\"correctly parse scientific notations with doubles with negatives 1\",\"code\":[\"a = 1d-34\",\"a = 1d-34i\",\"a = 1d-34j\"]},{\"name\":\"correctly parse scientific notations with doubles with negatives 2\",\"code\":[\"a = 1d-\",\"a = 1d-i\",\"a = 1d-j\"]},{\"name\":\"correctly parse new syntax for complex\",\"code\":[\"a = 1i\",\"a = 1j\"]},{\"name\":\"catch unfinished dot statement 1\",\"code\":\"a.\"},{\"name\":\"catch unfinished dot statement 2\",\"code\":\"a = b.\"},{\"name\":\"catch standalone dot\",\"code\":\"a = .\"},{\"name\":\"edge case scientific\",\"code\":\"a = .1e+12\"},{\"name\":\"solo dot\",\"code\":\".\"}]}","number-string.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36 + \\\"45\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36b + \\\"45ull\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'b\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'x\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'o\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"b\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"x\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"o\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XS\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XS\"}]}","number-string.complex-i.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.complex-i.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36i + \\\"45i\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36bi + \\\"45ulli\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'bi\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'xi\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'oi\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"bi\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"xi\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"oi\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XSi\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XSi\"}]}","number-string.complex-j.spec.ts":"{\"suiteName\":\"Validates special cases for number string parsing\",\"fileName\":\"number-string.complex-j.spec.ts\",\"tests\":[{\"name\":\"verify octal parsing\",\"code\":\"\\\"36j + \\\"45j\"},{\"name\":\"verify octal parsing\",\"code\":\"\\\"36bj + \\\"45ullj\"},{\"name\":\"verify single quote binary\",\"code\":\"'101010'bj\"},{\"name\":\"verify single quote hex\",\"code\":\"'10101'xj\"},{\"name\":\"verify single quote octal\",\"code\":\"'10101'oj\"},{\"name\":\"verify double quote binary\",\"code\":\"\\\"101010\\\"bj\"},{\"name\":\"verify double quote hex\",\"code\":\"\\\"10101\\\"xj\"},{\"name\":\"verify double quote octal\",\"code\":\"\\\"10101\\\"oj\"},{\"name\":\"verify case as hex\",\"code\":\"'7FFF'XSj\"},{\"name\":\"verify case as hex\",\"code\":\"'8FFF'XSj\"}]}","operators.compound.spec.ts":"{\"suiteName\":\"Validates compound operator parsing\",\"fileName\":\"operators.compound.spec.ts\",\"tests\":[{\"name\":\"parses with line continuation\",\"code\":[\"z *= $\",\" 5\"]},{\"name\":\"does not recurse with \\\"||\\\" operator\",\"code\":\"a || b || c\"},{\"name\":\"does not recurse with \\\"or\\\" operator\",\"code\":\"a or b or c\"},{\"name\":\"captures all statements with \\\"&&\\\" operator\",\"code\":\"a && b && c\"},{\"name\":\"captures all statements with \\\"&&\\\" operator\",\"code\":\"a and b and c\"}]}","operators.spec.ts":"{\"suiteName\":\"Validates operator parsing\",\"fileName\":\"operators.spec.ts\",\"tests\":[{\"name\":\"close on braces\",\"code\":\"{1+2}\"},{\"name\":\"close on brackets\",\"code\":\"[1+2]\"},{\"name\":\"close on parentheses\",\"code\":\"(1+2)\"},{\"name\":\"close on commas\",\"code\":\"1+2,3+4\"},{\"name\":\"close on then and else\",\"code\":\"if 1+2 then a = 3+4 else a = 4^3\"},{\"name\":\"close on do in loops\",\"code\":\"for i=0, 99-1 do print, i\"},{\"name\":\"operators with line continuations\",\"code\":[\"zach + $ \",\"awesome\"]},{\"name\":\"operators end on \\\"of\\\"\",\"code\":[\"case n_params()-1 of\",\" 0: call_method, method_name, oObj[i], _extra=e\",\" 1: call_method, method_name, oObj[i], p1, _extra=e\",\"endcase\"]},{\"name\":\"operators end on arrow function\",\"code\":\"*(*pState).pTitle->SetProperty, color=[255, 255, 255]\"},{\"name\":\"operators end on procedure method\",\"code\":\"*pTitle.SetProperty, color=[255, 255, 255]\"},{\"name\":\"operators do not end on function method\",\"code\":\"*pTitle.SetProperty(color=[255, 255, 255])\"},{\"name\":\"operators do not end on function method\",\"code\":\"*pTitle->SetProperty(color=[255, 255, 255])\"},{\"name\":\"special token for increment\",\"code\":[\"++a\",\"a++\"]},{\"name\":\"special token for decrement\",\"code\":[\"--a\",\"a+--\"]},{\"name\":\"next to each other\",\"code\":\"a = b++ + 5\"}]}","parentheses.spec.ts":"{\"suiteName\":\"Validates parentheses parsing\",\"fileName\":\"parentheses.spec.ts\",\"tests\":[{\"name\":\"parses standalone parentheses\",\"code\":\"(1 + 2)\"},{\"name\":\"separate function from parentheses\",\"code\":\"myFunc(1 + 2) * (1 + 2)\"},{\"name\":\"parses standalone parentheses with line continuation\",\"code\":[\"(1 + $ \",\" 2)\"]}]}","prompts.spec.ts":"{\"suiteName\":\"Validates prompt parsing\",\"fileName\":\"prompts.spec.ts\",\"tests\":[{\"name\":\"parses IDL prompt\",\"code\":\"IDL> print, 42\"},{\"name\":\"parses ENVI prompt\",\"code\":\"ENVI> print, 17\"}]}","properties.spec.ts":"{\"suiteName\":\"Validates property parsing\",\"fileName\":\"properties.spec.ts\",\"tests\":[{\"name\":\"parses property assignment\",\"code\":\"a.thing = 5\"},{\"name\":\"parses property access\",\"code\":\"b = a.thing\"},{\"name\":\"parses property access with line continuation\",\"code\":[\"b = $\",\" a.thing\"]},{\"name\":\"parses nested property access\",\"code\":\"b = a.thing1.thing2\"},{\"name\":\"parses property access as arguments\",\"code\":\"myPro, a.thing, b.thing\"},{\"name\":\"property example from IDL lib\",\"code\":\"(*state).bottomSelection = lMarkers.Count()-1\"},{\"name\":\"structure property via indexing\",\"code\":\"a = b.(i)\"}]}","python.spec.ts":"{\"suiteName\":\"Validates Python code parsing\",\"fileName\":\"python.spec.ts\",\"tests\":[{\"name\":\"parses IDL prompt\",\"code\":\">>>import numpy as np\"}]}","quotes.spec.ts":"{\"suiteName\":\"Validates quote parsing\",\"fileName\":\"quotes.spec.ts\",\"tests\":[{\"name\":\"parses standalone single quotes\",\"code\":\"'myFunc(1 + 2)'\"},{\"name\":\"parses standalone double quotes\",\"code\":\"\\\"myFunc(1 + 2)\\\"\"},{\"name\":\"verify single quotes without closing\",\"code\":\"'string\"},{\"name\":\"verify double quotes without closing\",\"code\":\"\\\"string\"},{\"name\":\"confusing single quote\",\"code\":\"hDefinition['schema']).StartsWith('IDLColorGradientDefinition', /FOLD_CASE)\"},{\"name\":\"confusing double quote\",\"code\":\"hDefinition[\\\"schema\\\"]).StartsWith(\\\"IDLColorGradientDefinition\\\", /FOLD_CASE)\"},{\"name\":\"quotes end at important statements 1\",\"code\":[\"if \\\"bad-quote\\\"then \\\"bad-quote\\\"else\"]},{\"name\":\"quotes end at important statements 2\",\"code\":[\"case \\\"bad-quote\\\"of\"]},{\"name\":\"quotes end at important statements 3\",\"code\":[\"for \\\"bad-quote\\\"do\"]},{\"name\":\"quotes end at important statements 4\",\"code\":[\"repeat 'bad-quote'until\"]},{\"name\":\"quotes end at important statements 5\",\"code\":[\"if 'bad-quote'then 'bad-quote'else\"]},{\"name\":\"quotes end at important statements 6\",\"code\":[\"case 'bad-quote'of\"]},{\"name\":\"quotes end at important statements 7\",\"code\":[\"for 'bad-quote'do\"]},{\"name\":\"quotes end at important statements 8\",\"code\":[\"repeat 'bad-quote'until\"]},{\"name\":\"verifies quote vs number is correctly identified\",\"code\":[\"arr = [\\\"0.00000000\\\"]\"]}]}","quotes.escaped.spec.ts":"{\"suiteName\":\"Validates escaped quote parsing\",\"fileName\":\"quotes.escaped.spec.ts\",\"tests\":[{\"name\":\"simple single quote\",\"code\":\"'Resolve_Routine, ''%s'', Is_Function=%d'\"},{\"name\":\"simple double quote\",\"code\":\"\\\"Resolve_Routine, \\\"\\\"%s\\\"\\\", Is_Function=%d\\\"\"},{\"name\":\"complex single quote\",\"code\":\"'Resolve_Routine, ''%s'', Is_Function=%d''lots of''other''string'\"},{\"name\":\"complex double quote\",\"code\":\"\\\"Resolve_Routine, \\\"\\\"%s\\\"\\\", Is_Function=%d\\\"\\\"lots of\\\"\\\"other\\\"\\\"string\\\"\"}]}","quotes.edge-cases.spec.ts":"{\"suiteName\":\"Validates edge case quote parsing\",\"fileName\":\"quotes.edge-cases.spec.ts\",\"tests\":[{\"name\":\"for number-string like strings\",\"code\":\"a = \\\"5\\\"\"}]}","routines.functions.spec.ts":"{\"suiteName\":\"Validates function parsing\",\"fileName\":\"routines.functions.spec.ts\",\"tests\":[{\"name\":\"parses standalone functions\",\"code\":\"myFunc(1 + 2)\"},{\"name\":\"parses nested functions\",\"code\":\"myFunc(myFunc2(_y7$) + 2)\"},{\"name\":\"separate function from parentheses\",\"code\":\"myFunc(1 + 2) * (1 + 2)\"},{\"name\":\"parses standalone functions with line continuations\",\"code\":[\"myFunc(1 $\",\" + 2)\"]},{\"name\":\"single-character function\",\"code\":\"a()\"}]}","routines.keywords.spec.ts":"{\"suiteName\":\"Validates keyword parsing\",\"fileName\":\"routines.keywords.spec.ts\",\"tests\":[{\"name\":\"parses keyword assignment\",\"code\":\"myfunc(a = 5)\"},{\"name\":\"parses multiple keywords\",\"code\":\"_otherfunc(a = 5, _b=42)\"},{\"name\":\"parses multiple keywords with line continuation\",\"code\":[\"myfunc(a = 5, $\",\" _b=42)\"]},{\"name\":\"parses keyword assignment with line continuation\",\"code\":[\"myfunc(a $\",\" = 5)\"]},{\"name\":\"parses variable assignment\",\"code\":\"_y = _superFunction(a = 5)\"}]}","routines.procedures.spec.ts":"{\"suiteName\":\"Validates procedure parsing\",\"fileName\":\"routines.procedures.spec.ts\",\"tests\":[{\"name\":\"parses standalone procedures\",\"code\":\"myPro, 1 + 2\"},{\"name\":\"separate pro from variables\",\"code\":\"myPro, arg1, arg2\"},{\"name\":\"pro with line continuations\",\"code\":[\"myPro, $\",\" arg1, arg2\"]},{\"name\":\"pro in loop after arguments and function\",\"code\":\"for i=0, 2*5-jello(1) do print, i\"},{\"name\":\"single-character procedure\",\"code\":\"a\"}]}","routines.spacing.spec.ts":"{\"suiteName\":\"Validates routine spacing\",\"fileName\":\"routines.spacing.spec.ts\",\"tests\":[{\"name\":\"functions\",\"code\":\"myFunc (1 + 2)\"},{\"name\":\"procedures\",\"code\":\"mypro ,\"},{\"name\":\"function method (dots)\",\"code\":\"a . method ()\"},{\"name\":\"function method (arrow)\",\"code\":\"a -> method ()\"},{\"name\":\"procedure method 1 (dots)\",\"code\":\"a . method \"},{\"name\":\"procedure method 2 (dots)\",\"code\":\"a . method , \"},{\"name\":\"procedure method 1 (arrow)\",\"code\":\"a -> method \"},{\"name\":\"procedure method 2 (arrow)\",\"code\":\"a -> method , \"}]}","routines.definitions.1.spec.ts":"{\"suiteName\":\"Validates routine parsing\",\"fileName\":\"routines.definitions.1.spec.ts\",\"tests\":[{\"name\":\"verifies procedure with arguments and keywords\",\"code\":[\"PRO EndMagic, arg1, $ ; comment\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"END\"]},{\"name\":\"verifies functions with arguments and keywords\",\"code\":[\"function myfunc, arg1, $ ; comment\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"end\"]},{\"name\":\"verifies procedure method with arguments and keywords\",\"code\":[\"PRO myclass::mymethod, arg1, $ ; comment\",\" ; skip empty lines\",\" arg2, KW1 = $\",\" kw1, KW2 = kw2\",\"\",\"END\"]},{\"name\":\"verifies function method with arguments and keywords\",\"code\":[\"function myfuncclass::mymethod, arg1, $ ; comment\",\"\",\" arg2, KW1 = $\",\"\",\" kw1, KW2 = kw2\",\"\",\"end\"]},{\"name\":\"verifies more than one routine\",\"code\":[\"Function f1\",\" return, 5\",\"end\",\"\",\"pro p1\",\" print, 42\",\"end\"]}]}","routines.definitions.2.spec.ts":"{\"suiteName\":\"Validates routine parsing\",\"fileName\":\"routines.definitions.2.spec.ts\",\"tests\":[{\"name\":\"verifies we only stop on \\\"end\\\"\",\"code\":[\"PRO EndMagic, Unit, Id\",\" PRINTF, Unit\",\"END\"]},{\"name\":\"verifies we parse names with \\\"!\\\"\",\"code\":[\"pro !sosobad,\",\"END\"]},{\"name\":\"verifies we parse method names with \\\"!\\\"\",\"code\":[\"pro !sosobad::method,\",\"END\"]},{\"name\":\"routines in a very bad single-line\",\"code\":\"FUNCTION VarName, Ptr & RETURN,'' & END\"}]}","string-literal.spec.ts":"{\"suiteName\":\"Verify string literal processing\",\"fileName\":\"string-literal.spec.ts\",\"tests\":[{\"name\":\"simple with substitution\",\"code\":\"a = `my string with ${expression + 5}`\"},{\"name\":\"simple without substitution\",\"code\":\"a = `my string without substitution`\"},{\"name\":\"properly capture nested literals\",\"code\":\"a = `start ${ `nested` } else`\"},{\"name\":\"complex nested case\",\"code\":\"a = `something ${func(a = b, `nested`, /kw) + 6*12} else ${5*5 + `something` + nested} some`\"},{\"name\":\"parse escaped backticks\",\"code\":\"a = `something \\\\` included `\"},{\"name\":\"preserve spacing when extracting tokens\",\"code\":\"a = ` first `\"},{\"name\":\"template literal string with formatting\",\"code\":\"a = `${1.234,\\\"%10.3f\\\"}`\"}]}","string-literal.multiline.spec.ts":"{\"suiteName\":\"Verify string literal processing with multi-line statements\",\"fileName\":\"string-literal.multiline.spec.ts\",\"tests\":[{\"name\":\"preserve spacing and handle multi-line string literals\",\"code\":[\"compile_opt idl2\",\"; thing\",\"a = ` first\",\" second\",\" third\",\"last`\",\"end\"]}]}","string-literal.escape.spec.ts":"{\"suiteName\":\"Verify string literal escape characters\",\"fileName\":\"string-literal.escape.spec.ts\",\"tests\":[{\"name\":\"for syntax highlighting\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"a = `\\\\a `\",\"end\"]}]}","structures.1.spec.ts":"{\"suiteName\":\"Validates structure parsing\",\"fileName\":\"structures.1.spec.ts\",\"tests\":[{\"name\":\"verifies simplest structure parsing\",\"code\":\"_z5$ = {thing}\"},{\"name\":\"verifies multi-line structure name parsing\",\"code\":[\"_17$ = { $\",\" thing}\"]},{\"name\":\"verifies simplest property parsing without structure name\",\"code\":\"_17$ = {thing:z}\"},{\"name\":\"verifies simplest property parsing without structure name and line continuation\",\"code\":[\"_17$ = { $\",\" thing:z}\"]},{\"name\":\"verifies simplest nested structure parsing\",\"code\":\"_z5$ = {thing1:{thing2:z}}\"},{\"name\":\"verifies structure with inheritance\",\"code\":\"_z5$ = {thing, inherits _jklol}\"},{\"name\":\"verifies all components in single-line\",\"code\":\"a17 = {_th1g, abc:def, b:5, c:f()}\"}]}","structures.2.spec.ts":"{\"suiteName\":\"Validates structure parsing\",\"fileName\":\"structures.2.spec.ts\",\"tests\":[{\"name\":\"verifies multiple structure names (even though wrong syntax)\",\"code\":\"a = {one,two,three,inherits thing, inherits other, prop:5} ; comment\"},{\"name\":\"verifies nested structures, line continuations, and comments\",\"code\":[\"_17$ = { $ ; something\",\" thing: {name, some:value}}\"]},{\"name\":\"verifies weird syntax for named structures\",\"code\":[\"new_event = {FILESEL_EVENT, parent, ev.top, 0L, $\",\"path+filename, 0L, theFilter}\"]},{\"name\":\"structure names with exclamation points\",\"code\":\"a = {!exciting}\"},{\"name\":\"structure names and then line continuation\",\"code\":\"void = {mlLabelingTool_GraphicOverlay $\"},{\"name\":\"inherits supports spaces\",\"code\":[\" void = {IDLitDataIDLArray2D, $\",\" inherits IDLitData}\"]}]}","unexpected.1.spec.ts":"{\"suiteName\":\"Validates unexpected closer parsing\",\"fileName\":\"unexpected.1.spec.ts\",\"tests\":[{\"name\":\"verifies we catch unexpected closers (other tests cover correctly catching real closers instead of these)\",\"code\":[\")\",\"]\",\"}\",\"endif\",\"endelse\",\"endfor\",\"endforeach\",\"endrep\",\"endwhile\",\"endswitch\",\"endcase\",\"end\"]}]}","unknown.spec.ts":"{\"suiteName\":\"Validates unknown token parsing\",\"fileName\":\"unknown.spec.ts\",\"tests\":[{\"name\":\"improper arrow function\",\"code\":\"sEvent.component-> $\"},{\"name\":\"text after comment\",\"code\":\"a = $ bad bad\"},{\"name\":\"unknown has right positioning with zero-width matches\",\"code\":\"scale=scale, $, $\"}]}"},"auto-post-processor-tests":{"arg-defs.spec.ts":"{\"suiteName\":\"Correctly extract argument definitions from code\",\"fileName\":\"arg-defs.spec.ts\",\"tests\":[{\"name\":\"Convert variables to arguments in standard routine definitions\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"Convert variables to arguments in routine method definition\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]}]}","arrows.spec.ts":"{\"suiteName\":\"Correctly map arrows\",\"fileName\":\"arrows.spec.ts\",\"tests\":[{\"name\":\"as procedure-method, but incomplete\",\"code\":[\"compile_opt idl2\",\"a->\",\"end\"]},{\"name\":\"as function method, but incomplete\",\"code\":[\"compile_opt idl2\",\"a = b->\",\"end\"]}]}","comment-blocks.1.spec.ts":"{\"suiteName\":\"Correctly map comments to comment blocks\",\"fileName\":\"comment-blocks.1.spec.ts\",\"tests\":[{\"name\":\"ignore normal comments\",\"code\":[\"compile_opt idl2\",\"; i am properly ignored like i should be\",\"a = 5\",\"end\"]},{\"name\":\"single-line blocks\",\"code\":[\"compile_opt idl2\",\";+ i am a basic block on only one line\",\"a = 5\",\"end\"]},{\"name\":\"multi-line blocks without end\",\"code\":[\"compile_opt idl2\",\";+\",\"; something about docs\",\"; like, really cool information\",\"a = 5\",\"end\"]},{\"name\":\"multi-line blocks with close\",\"code\":[\"compile_opt idl2\",\";+\",\"; worlds greatest documenter\",\";- ended\",\"a = 5\",\"end\"]},{\"name\":\"multi-line blocks with close\",\"code\":[\"compile_opt idl2\",\";+ definition of life\",\"a = 42\",\";+ second definition of life\",\"fortyTwo = 42\",\"end\"]}]}","comment-blocks.2.spec.ts":"{\"suiteName\":\"Advanced comment block cases\",\"fileName\":\"comment-blocks.2.spec.ts\",\"tests\":[{\"name\":\"end on block end and dont include excess comments\",\"code\":[\"compile_opt idl2\",\";+\",\"; worlds greatest documenter\",\";-\",\"; not included in block\",\"a = 5\",\"end\"]},{\"name\":\"allow two blocks next to each other\",\"code\":[\"compile_opt idl2\",\";+\",\"; first block\",\";-\",\";+\",\"; second block\",\";-\",\"a = 5\",\"end\"]},{\"name\":\"capture recursive blocks\",\"code\":[\"compile_opt idl2\",\";+\",\"; first block\",\";-\",\"\",\"if !true then begin\",\" ;+\",\" ; second block\",\" ;-\",\" a = 5\",\"endif\",\"\",\"end\"]}]}","comment-blocks.3.spec.ts":"{\"suiteName\":\"Confusing comment blocks \",\"fileName\":\"comment-blocks.3.spec.ts\",\"tests\":[{\"name\":\"ignore markdown lists\",\"code\":[\"compile_opt idl2\",\";+\",\"; worlds greatest documenter\",\"; - some bulleted list\",\"; - some bulleted list\",\";-\",\"a = 5\",\"end\"]}]}","control-options.spec.ts":"{\"suiteName\":\"Correctly map options for compound control statements\",\"fileName\":\"control-options.spec.ts\",\"tests\":[{\"name\":\"Convert variables to control options\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" common blockName ; ignore for now\",\" forward_function myfunc1, myfunc2, myfunc3\",\" goto, stmnt\",\"\",\"end\"]}]}","dot.spec.ts":"{\"suiteName\":\"Correctly map periods to dots\",\"fileName\":\"dot.spec.ts\",\"tests\":[{\"name\":\"as procedure-method or property access, but incomplete\",\"code\":[\"compile_opt idl2\",\"a.\",\"end\"]},{\"name\":\"as function method or property access, but incomplete\",\"code\":[\"compile_opt idl2\",\"a = b.\",\"end\"]},{\"name\":\"standalone 1\",\"code\":[\"compile_opt idl2\",\"a = .\",\"end\"]},{\"name\":\"standalone 2\",\"code\":[\"compile_opt idl2\",\".\",\"end\"]}]}","keywords.spec.ts":"{\"suiteName\":\"Correctly extract keyword names from routine calls\",\"fileName\":\"keywords.spec.ts\",\"tests\":[{\"name\":\"Convert variables to keywords when calling procedures\",\"code\":[\"compile_opt idl2\",\"mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\"\",\"end\"]},{\"name\":\"Convert variables to keywords when calling procedure methods\",\"code\":[\"compile_opt idl2\",\"obj.method, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\"\",\"end\"]},{\"name\":\"Convert variables to keywords when calling functions\",\"code\":[\"compile_opt idl2\",\"res = mypro(arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3)\",\"\",\"end\"]},{\"name\":\"Convert variables to keywords when calling function methods\",\"code\":[\"compile_opt idl2\",\"res = obj.method(arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3)\",\"\",\"end\"]}]}","keywords-binary.spec.ts":"{\"suiteName\":\"Correctly detect binary keywords\",\"fileName\":\"keywords-binary.spec.ts\",\"tests\":[{\"name\":\"in procedure\",\"code\":\"mypro, /kw1, /KW2\"},{\"name\":\"in procedure method\",\"code\":[\"myclass.method, $\",\" /KW3, KW=!true\"]},{\"name\":\"in function\",\"code\":\"a = myfunc(/KW1, /KW2)\"},{\"name\":\"in function method\",\"code\":[\"ZACH = AWESOME.SAUCE(/kw3, $\",\"/KW17, KW18 = !false)\"]},{\"name\":\"preserve other children after keyword\",\"code\":[\"compile_opt idl2\",\"tvcrs,x,y,/dev $\\t;Restore cursor\",\" kw=2\",\"\",\"end\"]},{\"name\":\"properly handle comments in function calls\",\"code\":[\"compile_opt idl2\",\"wDatatable = WIDGET_TABLE(id_datarow, $\",\"; FORMAT='(A)', $\",\" /RESIZEABLE_COLUMNS)\",\"\",\"end\"]}]}","keyword-defs.spec.ts":"{\"suiteName\":\"Correctly extract keyword definitions\",\"fileName\":\"keyword-defs.spec.ts\",\"tests\":[{\"name\":\"Convert variables to keywords in standard routine definitions\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"Convert variables to keywords in routine method definition\",\"code\":[\"pro mypro::mymethod, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"from complex example\",\"code\":[\"function TS_HANTS2, timeseries, $\",\"amplitudes = amp, $\",\"delta = delta, $\",\"dod = dod, $\",\"double = double, $\",\"err_tolerance = err_tolerance, $\",\"; FREQUENCIES=freq, $\",\"HIGH = HIGH, $\",\"low = low, $\",\"num_frequencies = num_frequencies, $\",\"num_period = num_period, $\",\"phases = phases, $\",\"range_maximum = range_maximum, $\",\"range_minimum = range_minimum, $\",\"time_sample = time_sample, $\",\"num_images = num_images\",\"\",\"compile_opt idl2\",\"\",\"a = IDL_Number.total()\",\"\",\"return, name\",\"end\"]}]}","main.spec.ts":"{\"suiteName\":\"Correctly maps main level tokens\",\"fileName\":\"main.spec.ts\",\"tests\":[{\"name\":\"do nothing without main level\",\"code\":[\"function myfunc\",\"compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"process single-line code 1\",\"code\":[\"a = plot(/TEST)\"]},{\"name\":\"process single-line code 2\",\"code\":[\"a = `${42, '42'}${42, '42'}`\"]},{\"name\":\"catch correct\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\"]},{\"name\":\"catch with no end\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\"]},{\"name\":\"catch with statements after the end\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\",\"; bad comment\",\"something = else\"]},{\"name\":\"ignore only comments\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"; another comment\"]},{\"name\":\"edge case\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"!null = myfunc()\"]}]}","operator.pointer-deref.basic.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.basic.spec.ts\",\"tests\":[{\"name\":\"ignore multiplication\",\"code\":[\"a = 6 * 7\"]},{\"name\":\"ignore multiplication\",\"code\":[\"a = (6) * (7)\"]},{\"name\":\"assignment\",\"code\":[\"a = *var\"]},{\"name\":\"after operators\",\"code\":[\"a = 5 + *var\"]},{\"name\":\"after mod operator\",\"code\":[\"a = mod *var\"]},{\"name\":\"after logical operators\",\"code\":[\"a = 5 le *var\"]},{\"name\":\"single line\",\"code\":[\"*ptr = 42\"]}]}","operator.pointer-deref.loops.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.loops.spec.ts\",\"tests\":[{\"name\":\"in for loop statements\",\"code\":[\"for i=*var, *other do *val = 42\"]},{\"name\":\"in foreach loop statements\",\"code\":[\"foreach val, *thing, key do *val = 42\"]},{\"name\":\"in while loop statements\",\"code\":[\"while *var do *val = 42\"]},{\"name\":\"in repeat loop statements\",\"code\":[\"repeat *val = 42 until *var\"]}]}","operator.pointer-deref.if.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.if.spec.ts\",\"tests\":[{\"name\":\"in if-then-else\",\"code\":[\"if *val then *var = 42 else *var = 84\"]}]}","operator.pointer-deref.case.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.case.spec.ts\",\"tests\":[{\"name\":\"all parts of case statement\",\"code\":[\"compile_opt idl2\",\"case *val of\",\" *thing: *other = 42\",\" else: *value = 84\",\"endcase\",\"end\"]}]}","operator.pointer-deref.routines.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.routines.spec.ts\",\"tests\":[{\"name\":\"in functions\",\"code\":[\"a = func(*val, *other, kw=*last)\"]},{\"name\":\"in function methods\",\"code\":[\"a = var.func(*val, *other, kw=*last)\"]},{\"name\":\"in procedure definitions\",\"code\":[\"function mypro\",\" compile_opt idl2\",\" *val = 5\",\" *val2 = 5\",\" return, !null\",\"end\"]},{\"name\":\"in procedures\",\"code\":[\"mypro, *val, *other, kw=*last\"]},{\"name\":\"in procedure methods\",\"code\":[\"var.mypro, *val, *other, kw=*last\"]},{\"name\":\"in multi-line procedures\",\"code\":[\"mypro,$\",\" *val\",\"end\"]},{\"name\":\"in procedure definitions\",\"code\":[\"pro mypro\",\"compile_opt idl2\",\" *val = 5\",\" *val2 = 5\",\" return\",\"end\"]}]}","operator.pointer-deref.paren.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.paren.spec.ts\",\"tests\":[{\"name\":\"as first statement in paren\",\"code\":[\"a = (*var)\"]}]}","operator.pointer-deref.struct.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.struct.spec.ts\",\"tests\":[{\"name\":\"after structure properties\",\"code\":[\"a = {prop: *ptr}\"]},{\"name\":\"after indexed structure properties\",\"code\":[\"a = var.(*thing)\"]}]}","operator.pointer-deref.switch.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.switch.spec.ts\",\"tests\":[{\"name\":\"all parts of switch statement\",\"code\":[\"\",\"compile_opt idl2\",\"switch *val of\",\" *thing: *other = 42\",\" *thing2: *other = 42\",\" else: *value = 84\",\"endcase\",\"end\"]}]}","operator.pointer-deref.ternary.spec.ts":"{\"suiteName\":\"Correctly identify pointer dereferencing\",\"fileName\":\"operator.pointer-deref.ternary.spec.ts\",\"tests\":[{\"name\":\"all parts of ternary operators\",\"code\":[\"a = *val ? *truthy : *falsy\"]}]}","operator.indexing.array.spec.ts":"{\"suiteName\":\"Correctly identify array indexing\",\"fileName\":\"operator.indexing.array.spec.ts\",\"tests\":[{\"name\":\"all parts of ternary operators\",\"code\":[\"compile_opt idl2\",\"subsel = sel[*, 1:*val]\",\"end\"]}]}","operator.pointer-deref.regression.spec.ts":"{\"suiteName\":\"Correctly identify array indexing\",\"fileName\":\"operator.pointer-deref.regression.spec.ts\",\"tests\":[{\"name\":\"instead of de-referencing\",\"code\":[\"compile_opt idl2\",\"temp = reform(mask[i*8 : min([s[1] - 1, i*8 + 7]), j])\",\"end\"]}]}","strings.spec.ts":"{\"suiteName\":\"Correctly merge strings together\",\"fileName\":\"strings.spec.ts\",\"tests\":[{\"name\":\"merge single quotes\",\"code\":[\"a = 'string''escaped'\"]},{\"name\":\"merge double quotes\",\"code\":[\"a = \\\"string\\\"\\\"escaped\\\"\"]},{\"name\":\"ignore single quotes that cannot be merged\",\"code\":[\"a = 'string' 'escaped'\"]},{\"name\":\"ignore double quotes that cannot be merged\",\"code\":[\"a = \\\"string\\\" \\\"escaped\\\"\"]}]}","var-not-function.spec.ts":"{\"suiteName\":\"Correctly identify variables instead of function calls\",\"fileName\":\"var-not-function.spec.ts\",\"tests\":[{\"name\":\"for simple case\",\"code\":[\";+ my var\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt strictarr\",\"code\":[\"compile_opt strictarr\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl2\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl3\",\"code\":[\"compile_opt idl3\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]}]}"},"auto-syntax-validator-tests":{"bad-routine-def.spec.ts":"{\"suiteName\":\"Verify that we can parse and report problems\",\"fileName\":\"bad-routine-def.spec.ts\",\"tests\":[{\"name\":\"for bad function\",\"code\":[\"function \",\"\",\"; pro test_myurl\",\"\",\"a = curl_easy_init()\",\"curlopt_header = 42\",\"print, 'curl_easy_setopt', curl_easy_setopt(a, curlopt_header, 1)\",\"curlopt_url = 10002\",\"print, 'curl_easy_setopt', curl_easy_setopt(a, curlopt_url, 'http://www.google.com')\",\"print, 'curl_easy_perform', curl_easy_perform(a)\",\"curl_easy_cleanup, a\",\"end\"]},{\"name\":\"for bad pro\",\"code\":[\"pro \",\"\",\"; pro test_myurl\",\"\",\"a = curl_easy_init()\",\"curlopt_header = 42\",\"print, 'curl_easy_setopt', curl_easy_setopt(a, curlopt_header, 1)\",\"curlopt_url = 10002\",\"print, 'curl_easy_setopt', curl_easy_setopt(a, curlopt_url, 'http://www.google.com')\",\"print, 'curl_easy_perform', curl_easy_perform(a)\",\"curl_easy_cleanup, a\",\"end\"]}]}","code.0.not-closed.spec.ts":"{\"suiteName\":\"Detects problems with statements not being closed\",\"fileName\":\"code.0.not-closed.spec.ts\",\"tests\":[{\"name\":\"parentheses\",\"code\":\"(\"},{\"name\":\"brackets\",\"code\":\"[\"},{\"name\":\"structures\",\"code\":\"{\"},{\"name\":\"functions\",\"code\":\"myfunc(\"},{\"name\":\"blocks\",\"code\":\"begin\"},{\"name\":\"switch\",\"code\":\"switch\"},{\"name\":\"case\",\"code\":\"case\"},{\"name\":\"procedures\",\"code\":\"pro mypro\"},{\"name\":\"functions\",\"code\":\"function myfunc\"},{\"name\":\"across line boundaries\",\"code\":[\"( $\",\" ;something\"]},{\"name\":\"only report last instance of unclosed in main\",\"code\":[\"compile_opt idl2\",\"p = plot(var var, $\",\" plot(var var\",\"end\"]},{\"name\":\"only report last instance of unclosed in routine\",\"code\":[\"pro myAwesomePro\",\"compile_opt idl2\",\"p = plot(var var, $\",\" plot(var var\",\"end\"]}]}","code.1.unexpected-closer.spec.ts":"{\"suiteName\":\"Detects unexpected closers\",\"fileName\":\"code.1.unexpected-closer.spec.ts\",\"tests\":[{\"name\":\"finds all unexpected closers\",\"code\":[\")\",\"]\",\"}\",\"endif\",\"endelse\",\"endfor\",\"endforeach\",\"endrep\",\"endwhile\",\"endswitch\",\"endcase\",\"end\"]},{\"name\":\"correctly processes routines and expects no errors\",\"code\":[\"Function f1\",\" if keyword_set(fclip) then begin\",\" return, 1\",\" endif\",\"end\"]}]}","code.3.after-main.spec.ts":"{\"suiteName\":\"Detects problems after main level\",\"fileName\":\"code.3.after-main.spec.ts\",\"tests\":[{\"name\":\"statements after main level\",\"code\":[\"compile_opt idl2\",\"end\",\"a = 5\"]},{\"name\":\"allow comments after main\",\"code\":[\"compile_opt idl2\",\"end\",\"; ok\"]}]}","code.6.todo.spec.ts":"{\"suiteName\":\"Detects TODO statements\",\"fileName\":\"code.6.todo.spec.ts\",\"tests\":[{\"name\":\"with basic lower-case comment\",\"code\":\"; todo: something\"},{\"name\":\"with basic upper-case comment\",\"code\":\"; todo: something\"}]}","code.7.unknown-token.spec.ts":"{\"suiteName\":\"Detects unknown tokens\",\"fileName\":\"code.7.unknown-token.spec.ts\",\"tests\":[{\"name\":\"with example in structure\",\"code\":\"a = {1+2}\"},{\"name\":\"after line continuation\",\"code\":[\"compile_opt idl2\",\"a = $ , $ ; ok\",\"42\",\"end\"]},{\"name\":\"ternary without assignment\",\"code\":\"!true ? a : b\"},{\"name\":\"comma in assignment\",\"code\":\"a = ,\"},{\"name\":\"quotes in structures 1\",\"code\":\"a = {'bad'}\"},{\"name\":\"quotes in structures 2\",\"code\":\"a = {\\\"bad\\\"}\"}]}","code.8.illegal-arrow.spec.ts":"{\"suiteName\":\"Detects illegal arrows\",\"fileName\":\"code.8.illegal-arrow.spec.ts\",\"tests\":[{\"name\":\"missing super/method\",\"code\":[\"compile_opt idl2\",\"a = b-> $\",\"method\",\"end\"]},{\"name\":\"missing method with super before\",\"code\":[\"compile_opt idl2\",\"oContainer = self->IDLitContainer:: $\",\"method\",\"end\"]}]}","code.9.illegal-comma.spec.ts":"{\"suiteName\":\"Detects illegal commas\",\"fileName\":\"code.9.illegal-comma.spec.ts\",\"tests\":[{\"name\":\"after assignment\",\"code\":\"a = ,\"},{\"name\":\"standalone\",\"code\":\",\"},{\"name\":\"in right place\",\"code\":[\"a = something()\",\",\"]},{\"name\":\"in parentheses\",\"code\":[\"a = (,)\"]},{\"name\":\"in switch\",\"code\":[\"compile_opt idl2\",\"switch a, of\",\" , !true: , \",\"endswitch\",\"end\"]},{\"name\":\"in case\",\"code\":[\"compile_opt idl2\",\"case a, of\",\" , !true: , \",\"endcase\",\"end\"]},{\"name\":\"in ternary\",\"code\":[\"a = !true ? ,'bad' : ,'still bad'\"]}]}","code.10.illegal-colon.spec.ts":"{\"suiteName\":\"Detects illegal colon\",\"fileName\":\"code.10.illegal-colon.spec.ts\",\"tests\":[{\"name\":\"standalone\",\"code\":\":\"},{\"name\":\"with reserved word in jump statement\",\"code\":\"break:\"},{\"name\":\"function call\",\"code\":\"myfunc(a:b)\"},{\"name\":\"bad array syntax\",\"code\":\"myarr(a:b)\"},{\"name\":\"ignore lambda functions\",\"code\":\"a = lambda(x:x+2)\"}]}","code.11.illegal-include.spec.ts":"{\"suiteName\":\"Detects illegal include statements\",\"fileName\":\"code.11.illegal-include.spec.ts\",\"tests\":[{\"name\":\"correctly find no problems\",\"code\":\"@includeme\"},{\"name\":\"don't find in functions\",\"code\":\"a = myfunc(@bad)\"},{\"name\":\"don't find in expressions\",\"code\":\"a = @include_wrong + @way_bad\"}]}","code.12.reserved-var.spec.ts":"{\"suiteName\":\"Detects reserved variable names. Not all are detected as you might think and require other syntax rules to verify\",\"fileName\":\"code.12.reserved-var.spec.ts\",\"tests\":[{\"name\":\"correctly detects \\\"for\\\"\",\"code\":\"a = for\"},{\"name\":\"correctly detects \\\"foreach\\\"\",\"code\":\"a = foreach\"},{\"name\":\"correctly detects \\\"while\\\"\",\"code\":\"a = while\"},{\"name\":\"correctly detects \\\"do\\\"\",\"code\":\"a = do\"},{\"name\":\"correctly detects \\\"repeat\\\"\",\"code\":\"a = repeat\"},{\"name\":\"correctly detects \\\"until\\\"\",\"code\":\"a = until\"},{\"name\":\"correctly detects \\\"if\\\"\",\"code\":\"a = if\"},{\"name\":\"correctly detects \\\"then\\\"\",\"code\":\"a = then\"},{\"name\":\"correctly detects \\\"else\\\"\",\"code\":\"a = else\"},{\"name\":\"correctly detects \\\"switch\\\"\",\"code\":\"a = switch\"},{\"name\":\"correctly detects \\\"case\\\"\",\"code\":\"a = case\"},{\"name\":\"correctly detects \\\"of\\\"\",\"code\":\"a = of\"},{\"name\":\"correctly detects \\\"begin\\\"\",\"code\":\"a = begin\"},{\"name\":\"correctly detects \\\"end\\\"\",\"code\":\"a = end\"},{\"name\":\"correctly detects \\\"endif\\\"\",\"code\":\"a = endif\"},{\"name\":\"correctly detects \\\"endelse\\\"\",\"code\":\"a = endelse\"},{\"name\":\"correctly detects \\\"endfor\\\"\",\"code\":\"a = endfor\"},{\"name\":\"correctly detects \\\"endforeach\\\"\",\"code\":\"a = endforeach\"},{\"name\":\"correctly detects \\\"endrep\\\"\",\"code\":\"a = endrep\"},{\"name\":\"correctly detects \\\"endwhile\\\"\",\"code\":\"a = endwhile\"},{\"name\":\"correctly detects \\\"endswitch\\\"\",\"code\":\"a = endswitch\"},{\"name\":\"correctly detects \\\"endcase\\\"\",\"code\":\"a = endcase\"},{\"name\":\"correctly detects \\\"pro\\\"\",\"code\":\"a = pro\"},{\"name\":\"correctly detects \\\"function\\\"\",\"code\":\"a = function\"},{\"name\":\"correctly detects \\\"break\\\"\",\"code\":\"a = break\"},{\"name\":\"correctly detects \\\"continue\\\"\",\"code\":\"a = continue\"},{\"name\":\"correctly detects \\\"common\\\"\",\"code\":\"a = common\"},{\"name\":\"correctly detects \\\"compile_opt\\\"\",\"code\":\"a = compile_opt\"},{\"name\":\"correctly detects \\\"forward_function\\\"\",\"code\":\"a = forward_function\"},{\"name\":\"correctly detects \\\"goto\\\"\",\"code\":\"a = goto\"},{\"name\":\"correctly detects \\\"mod\\\"\",\"code\":\"a = mod\"},{\"name\":\"correctly detects \\\"not\\\"\",\"code\":\"a = not\"},{\"name\":\"correctly detects \\\"eq\\\"\",\"code\":\"a = eq\"},{\"name\":\"correctly detects \\\"ne\\\"\",\"code\":\"a = ne\"},{\"name\":\"correctly detects \\\"le\\\"\",\"code\":\"a = le\"},{\"name\":\"correctly detects \\\"lt\\\"\",\"code\":\"a = lt\"},{\"name\":\"correctly detects \\\"ge\\\"\",\"code\":\"a = ge\"},{\"name\":\"correctly detects \\\"gt\\\"\",\"code\":\"a = gt\"},{\"name\":\"correctly detects \\\"and\\\"\",\"code\":\"a = and\"},{\"name\":\"correctly detects \\\"or\\\"\",\"code\":\"a = or\"},{\"name\":\"correctly detects \\\"xor\\\"\",\"code\":\"a = xor\"},{\"name\":\"correctly detects \\\"inherits\\\"\",\"code\":\"a = inherits\"}]}","code.13.illegal-ternary.spec.ts":"{\"suiteName\":\"Detects illegal ternary operators\",\"fileName\":\"code.13.illegal-ternary.spec.ts\",\"tests\":[{\"name\":\"correctly find no problems\",\"code\":\"a = !true ? 'yes' : 'no'\"},{\"name\":\"find problem\",\"code\":\"!true ? 'yes' : 'no'\"}]}","code.14.colon-in-func.spec.ts":"{\"suiteName\":\"Detects illegal colons in functions\",\"fileName\":\"code.14.colon-in-func.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a = var(0:-1)\"}]}","code.15.colon-in-func-method.spec.ts":"{\"suiteName\":\"Detects illegal colons in function methods\",\"fileName\":\"code.15.colon-in-func-method.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a = objOrStruct.var(0:-1)\"}]}","code.16.double-token.spec.ts":"{\"suiteName\":\"Detects two tokens next to each other\",\"fileName\":\"code.16.double-token.spec.ts\",\"tests\":[{\"name\":\"variables\",\"code\":\"procedure, var1 var2\"},{\"name\":\"functions\",\"code\":\"func1() func2()\"},{\"name\":\"operators\",\"code\":\"a + + b\"},{\"name\":\"commas\",\"code\":\"mypro,,\"},{\"name\":\"valid structures\",\"code\":\"a = {mystruct, {known:val}}\"},{\"name\":\"bad structures\",\"code\":\"a = {{known:val}}\"},{\"name\":\"ignore comments\",\"code\":[\"; first\",\";second\"]},{\"name\":\"OK separate lines\",\"code\":[\"pro1\",\"pro2\"]},{\"name\":\"All of these operators can be next to each other\",\"code\":[\"compile_opt idl2\",\"a = b && ~c && d\",\"a = b || ~c || d\",\"a = b not ~c not d\",\"a = b eq ~c eq d\",\"a = b ne ~c ne d\",\"a = b le ~c le d\",\"a = b lt ~c lt d\",\"a = b ge ~c gt d\",\"a = b gt ~c gt d\",\"a = b and ~c and d\",\"a = b or ~c or d\",\"a = b xor ~c xor d\",\"a = b.prop.prop.prop\",\"a = 42 & b = 42 & c = 42\",\"tol = (N_ELEMENTS(tolIn) eq 1) ? tolIn[0] : use_double ? 2d-12 : 1e-5\",\"end\"]},{\"name\":\"ignore template escape characters\",\"code\":[\"a = `\\\\r\\\\r\\\\n\\\\n`\"]},{\"name\":\"ignore nested function methods (caught elsewhere)\",\"code\":[\"a = var.myfunc().ohNotOk()\"]}]}","code.16.double-token.exclusions1.spec.ts":"{\"suiteName\":\"Allows these tokens next to each other\",\"fileName\":\"code.16.double-token.exclusions1.spec.ts\",\"tests\":[{\"name\":\"string literal expressions\",\"code\":\"a = `${42}${42}`\"}]}","code.17.illegal-struct.spec.ts":"{\"suiteName\":\"Detects illegal colons in function methods\",\"fileName\":\"code.17.illegal-struct.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a ={{}}\"}]}","code.18.illegal-paren.spec.ts":"{\"suiteName\":\"Detects illegal colons in function methods\",\"fileName\":\"code.18.illegal-paren.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a = {()}\"}]}","code.19.illegal-bracket.spec.ts":"{\"suiteName\":\"Detects illegal colons in function methods\",\"fileName\":\"code.19.illegal-bracket.spec.ts\",\"tests\":[{\"name\":\"find problem\",\"code\":\"a = {[]}\"}]}","code.20.return-vals-pro.spec.ts":"{\"suiteName\":\"Detects invalid return statements in procedures\",\"fileName\":\"code.20.return-vals-pro.spec.ts\",\"tests\":[{\"name\":\"ok in procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"ok in main\",\"code\":[\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return,\",\"end\"]},{\"name\":\"bad in objects\",\"code\":[\"pro mypro::method\",\" compile_opt idl2\",\" return,\",\"end\"]},{\"name\":\"bad in main\",\"code\":[\" compile_opt idl2\",\" return,\",\"end\"]},{\"name\":\"ok with comment after return\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return ; done\",\"end\"]}]}","code.21.return-vals-func.spec.ts":"{\"suiteName\":\"Detects invalid return statements in functions (too many vals)\",\"fileName\":\"code.21.return-vals-func.spec.ts\",\"tests\":[{\"name\":\"ok\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1,2\",\"end\"]},{\"name\":\"bad in objects\",\"code\":[\"function myfunc::method\",\" compile_opt idl2\",\" return,1,2\",\"end\"]},{\"name\":\"return value from function OK\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,weirdCall(1,2,3)\",\"end\"]},{\"name\":\"ok with comment after return\",\"code\":[\"function mypro\",\" compile_opt idl2\",\" return, 1 ; done\",\"end\"]}]}","code.22.return-vals-missing-func.spec.ts":"{\"suiteName\":\"Detects invalid return statements in functions (no val)\",\"fileName\":\"code.22.return-vals-missing-func.spec.ts\",\"tests\":[{\"name\":\"ok\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad in objects\",\"code\":[\"function myfunc::method\",\" compile_opt idl2\",\" return\",\"end\"]}]}","code.29.reserved-pro.spec.ts":"{\"suiteName\":\"Detects reserved procedures\",\"fileName\":\"code.29.reserved-pro.spec.ts\",\"tests\":[{\"name\":\"ok procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro WRITEU\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.30.reserved-func.spec.ts":"{\"suiteName\":\"Detects reserved functions\",\"fileName\":\"code.30.reserved-func.spec.ts\",\"tests\":[{\"name\":\"ok function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad function\",\"code\":[\"function label_region\",\" compile_opt idl2\",\" return,1\",\"end\"]}]}","code.31.return-missing.spec.ts":"{\"suiteName\":\"Detects missing return procedure in functions\",\"fileName\":\"code.31.return-missing.spec.ts\",\"tests\":[{\"name\":\"ok function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"ok in methods\",\"code\":[\"function myfunc::method\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad in methods\",\"code\":[\"function myfunc::method\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.32.routines-first.spec.ts":"{\"suiteName\":\"Detects invalid tokens before routine definition\",\"fileName\":\"code.32.routines-first.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\"@include\",\"\",\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\"]},{\"name\":\"all the problems\",\"code\":[\"; this is OK\",\"this = wrong * 5\",\"\",\"; this is OK too\",\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"; main level\",\"something = 42\",\"end\"]}]}","code.33.unclosed-main.spec.ts":"{\"suiteName\":\"Detects missing end to main level program\",\"fileName\":\"code.33.unclosed-main.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\"]},{\"name\":\"all the problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\"]},{\"name\":\"problems after end\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\",\"a = 17\"]}]}","code.33.unclosed-main.notebooks.spec.ts":"{\"suiteName\":\"Detects missing end to main level program\",\"fileName\":\"code.33.unclosed-main.notebooks.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"no problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"compile_opt idl2\",\"; main level\",\"something = 42\"],\"config\":{\"isNotebook\":true}},{\"name\":\"no problems\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\",\"\",\"a = myfunc()\"],\"config\":{\"isNotebook\":true}}]}","code.34.empty-main.spec.ts":"{\"suiteName\":\"Detects empty main level programs\",\"fileName\":\"code.34.empty-main.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\"; main level\",\"compile_opt idl2\",\"something = 42\",\"end\"]},{\"name\":\"all the problems\",\"code\":[\"; main level\",\"end\"]},{\"name\":\"also problems\",\"code\":[\"\",\"end\"]}]}","code.35.after-continuation.spec.ts":"{\"suiteName\":\"Detects invalid text after line continuations\",\"fileName\":\"code.35.after-continuation.spec.ts\",\"tests\":[{\"name\":\"no problems with nothing after continuation\",\"code\":[\"compile_opt idl2\",\"something = $\",\" 5\",\"end\"]},{\"name\":\"no problems with comment\",\"code\":[\"compile_opt idl2\",\"something = $ ; ok\",\" 5\",\"end\"]},{\"name\":\"problems\",\"code\":[\"compile_opt idl2\",\"something = $ bad\",\" 5\",\"end\"]},{\"name\":\"problems, same location as previous test\",\"code\":[\"compile_opt idl2\",\"something = $ bad ; ok\",\" 5\",\"end\"]}]}","code.36.reserved-pro-method.spec.ts":"{\"suiteName\":\"Detects reserved procedure methods\",\"fileName\":\"code.36.reserved-pro-method.spec.ts\",\"tests\":[{\"name\":\"ok procedure method\",\"code\":[\"pro IDLffVideoRead::myownmethod\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad procedure method\",\"code\":[\"pro IDLffVideoRead::Cleanup\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.37.reserved-func-method.spec.ts":"{\"suiteName\":\"Detects reserved function methods\",\"fileName\":\"code.37.reserved-func-method.spec.ts\",\"tests\":[{\"name\":\"ok function method\",\"code\":[\"function list::myownmethod\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad function method\",\"code\":[\"function list::where\",\" compile_opt idl2\",\" return,1\",\"end\"]}]}","code.38.no-comp-opt.spec.ts":"{\"suiteName\":\"Detects missing compile options\",\"fileName\":\"code.38.no-comp-opt.spec.ts\",\"tests\":[{\"name\":\"ok function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" return,1\",\"end\"]},{\"name\":\"ok procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" return\",\"end\"]},{\"name\":\"ok main\",\"code\":[\"compile_opt idl2\",\"; main level program\",\" a = 5\",\"end\"]},{\"name\":\"bad main\",\"code\":[\"; main level program\",\" a = 5\",\"end\"]}]}","code.38.no-comp-opt.notebooks.spec.ts":"{\"suiteName\":\"Detects missing compile options\",\"fileName\":\"code.38.no-comp-opt.notebooks.spec.ts\",\"tests\":[{\"name\":\"ok function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" return,1\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" return,1\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"ok procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" return\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" return\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"ok main\",\"code\":[\"compile_opt idl2\",\"; main level program\",\" a = 5\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"bad main\",\"code\":[\"; main level program\",\" a = 5\",\"end\"],\"config\":{\"isNotebook\":true}}]}","code.39.no-idl2.spec.ts":"{\"suiteName\":\"Detects missing compile option idl2\",\"fileName\":\"code.39.no-idl2.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt hidden\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt hidden\",\" return\",\"end\"]},{\"name\":\"don't complain about idl3\",\"code\":[\"pro mypro\",\" compile_opt idl3\",\" return\",\"end\"]}]}","code.40.illegal-comp-opt.spec.ts":"{\"suiteName\":\"Detects missing compile options\",\"fileName\":\"code.40.illegal-comp-opt.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt idl2, bad1\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2, bad2\",\" return\",\"end\"]}]}","code.41.empty-comp-opt.spec.ts":"{\"suiteName\":\"Detects compile opt without options\",\"fileName\":\"code.41.empty-comp-opt.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt\",\" return\",\"end\"]}]}","code.42.use-idl2.spec.ts":"{\"suiteName\":\"Detects compile opt without options\",\"fileName\":\"code.42.use-idl2.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt defint32, strictarr\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt defint32, strictarr\",\" return\",\"end\"]}]}","code.43.expected-comma.spec.ts":"{\"suiteName\":\"Detects statements that do expect a comma first\",\"fileName\":\"code.43.expected-comma.spec.ts\",\"tests\":[{\"name\":\"in go to\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" goto jumper\",\"end\"]},{\"name\":\"in procedure method call\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" p = plot(/TEST)\",\" p.method abc\",\"end\"]},{\"name\":\"in procedure call\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" print something\",\"end\"]},{\"name\":\"in routine name\",\"code\":[\"pro mypro var1\",\" compile_opt idl2\",\"end\"]}]}","code.44.unexpected-comma.spec.ts":"{\"suiteName\":\"Detects statements that don't expect a comma first\",\"fileName\":\"code.44.unexpected-comma.spec.ts\",\"tests\":[{\"name\":\"verify braces are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" a = b[,]\",\"end\"]},{\"name\":\"verify compile_opt is caught\",\"code\":[\"pro mypro\",\" compile_opt, idl2\",\"end\"]},{\"name\":\"verify common blocks are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" common, named\",\"end\"]},{\"name\":\"verify forward function is caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" forward_function, funcy\",\"end\"]},{\"name\":\"verify function calls are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" a = func(,)\",\"end\"]},{\"name\":\"verify function method calls are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" a = b.func(,)\",\"end\"]},{\"name\":\"verify for loops are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" for, i=0,100 do print, i\",\"end\"]},{\"name\":\"verify foreach loops are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" foreach, val, arr do print, val\",\"end\"]},{\"name\":\"verify structures are caught\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" a = {,name}\",\"end\"]}]}","code.45.multiple-comp-opt.spec.ts":"{\"suiteName\":\"Detects multiple compile_opt statements\",\"fileName\":\"code.45.multiple-comp-opt.spec.ts\",\"tests\":[{\"name\":\"bad function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\" compile_opt idl2\",\" return,1\",\"end\"]},{\"name\":\"bad procedure\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" compile_opt idl2\",\" return\",\"end\"]},{\"name\":\"bad main\",\"code\":[\" compile_opt idl2\",\" compile_opt idl2\",\"end\"]}]}","code.46.unclosed-quote.spec.ts":"{\"suiteName\":\"Detects unclosed quotes\",\"fileName\":\"code.46.unclosed-quote.spec.ts\",\"tests\":[{\"name\":\"ok double quote\",\"code\":[\"a = \\\"good\\\"\"]},{\"name\":\"bad double quote\",\"code\":[\"a = \\\"bad\"]},{\"name\":\"verify exclude fancy numbers\",\"code\":[\"a = \\\"0\"]},{\"name\":\"ok single quote\",\"code\":[\"a = 'good'\"]},{\"name\":\"bad single quote\",\"code\":[\"a = 'bad\"]}]}","code.47.args-first.spec.ts":"{\"suiteName\":\"Detects bad argument definitions\",\"fileName\":\"code.47.args-first.spec.ts\",\"tests\":[{\"name\":\"ok args in routine\",\"code\":[\"pro mypro, arg1, arg2, arg3, $\",\" arg4, arg5\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"bad args in routine\",\"code\":[\"pro mypro, arg1, arg2, arg3, $\",\" arg4, arg5, KW1 = kw1, $\",\" arg6, arg7\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"ok args in routine method\",\"code\":[\"pro myclass::mymethod, arg1, arg2, arg3, $\",\" arg4, arg5\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"bad args in routine method\",\"code\":[\"pro myclass::mymethod, arg1, arg2, arg3, $\",\" arg4, arg5, KW1 = kw1, $\",\" arg6, arg7\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.48.docs-missing-arg.spec.ts":"{\"suiteName\":\"Detects args missing from docs\",\"fileName\":\"code.48.docs-missing-arg.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\";\",\"; :Params:\",\"; var1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]}]}","code.49.no-args-to-doc.spec.ts":"{\"suiteName\":\"Detects documented args when there are no args\",\"fileName\":\"code.49.no-args-to-doc.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\";\",\"; :Params:\",\"; var1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";\",\"; :Params:\",\"; var1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod\",\" compile_opt idl2\",\"end\"]}]}","code.50.docs-missing-kw.spec.ts":"{\"suiteName\":\"Detects keywords missing from docs\",\"fileName\":\"code.50.docs-missing-kw.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\";\",\"; :Keywords:\",\"; KW1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";\",\";-\",\"pro myclass::mymethod, KW1=kw1\",\" compile_opt idl2\",\"end\"]}]}","code.51.no-kws-to-doc.spec.ts":"{\"suiteName\":\"Detects documented keywords when there are no keywords\",\"fileName\":\"code.51.no-kws-to-doc.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\";\",\"; :Keywords:\",\"; KW1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";\",\"; :Keywords:\",\"; KW1: in, optional, type=boolean\",\"; My favorite argument\",\";\",\";-\",\"pro myclass::mymethod\",\" compile_opt idl2\",\"end\"]}]}","code.52.docs-missing-return.spec.ts":"{\"suiteName\":\"Detects documented keywords when there are no keywords\",\"fileName\":\"code.52.docs-missing-return.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Returns: number\",\";-\",\"function myfunc\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\";-\",\"function myfunc\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.53.docs-invalid-in-out.spec.ts":"{\"suiteName\":\"Detects when in/out is incorrect for docs\",\"fileName\":\"code.53.docs-invalid-in-out.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, type=boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: wrong, optional, type=boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]}]}","code.54.docs-invalid-require.spec.ts":"{\"suiteName\":\"Detects when required/optional is incorrect for docs\",\"fileName\":\"code.54.docs-invalid-require.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, WRONG, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]}]}","code.56.docs-invalid-private.spec.ts":"{\"suiteName\":\"Detects when private/public is incorrect for docs\",\"fileName\":\"code.56.docs-invalid-private.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, hidden\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]}]}","code.57.docs-too-few-params.spec.ts":"{\"suiteName\":\"Detects when not enough documentation parameters are present\",\"fileName\":\"code.57.docs-too-few-params.spec.ts\",\"tests\":[{\"name\":\"no problems for args\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem for args\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"no problems for keywords\",\"code\":[\";+\",\"; :Keywords:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, VAR1=var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem for keywords\",\"code\":[\";+\",\"; :Keywords:\",\"; var1: in, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, VAR1=var1\",\" compile_opt idl2\",\"end\"]}]}","code.58.docs-too-many-params.spec.ts":"{\"suiteName\":\"Detects when too many documentation parameters are present\",\"fileName\":\"code.58.docs-too-many-params.spec.ts\",\"tests\":[{\"name\":\"no problems for args\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem for args\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, private, mcScrooge\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"no problems for keywords\",\"code\":[\";+\",\"; :Keywords:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, VAR1=var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem for keywords\",\"code\":[\";+\",\"; :Keywords:\",\"; var1: in, optional, boolean, public, somethingWrong\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, VAR1=var1\",\" compile_opt idl2\",\"end\"]}]}","code.59.docs-left-align.spec.ts":"{\"suiteName\":\"Detects when docs are not left-aligned as expected\",\"fileName\":\"code.59.docs-left-align.spec.ts\",\"tests\":[{\"name\":\"no problems in params/keywords\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\"; And another line\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in params/keywords\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\"; And another line\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in other blocks\",\"code\":[\";+\",\"; First line is great\",\"; THEN CHAOS ENSUES\",\";\",\"; :Params:\",\"; var1: in, optional, boolean\",\"; My favorite argument\",\";-\",\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"no problems in variables\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+\",\" ; Some things are really awesome\",\" ; and need a big description\",\" ;-\",\" a = 42\",\"end\"]},{\"name\":\"problems in variables\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+\",\" ; Some things are really awesome\",\" ;and need a big description\",\" ;-\",\" a = 42\",\"end\"]}]}","code.60.docs-return-has-no-type.spec.ts":"{\"suiteName\":\"Detects when the returns tag for docs is missing the data type\",\"fileName\":\"code.60.docs-return-has-no-type.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns:\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.61.docs-return-invalid.spec.ts":"{\"suiteName\":\"Detects when the returns tag has too much information\",\"fileName\":\"code.61.docs-return-invalid.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\"; Fun fact about zach\",\"; he is a vegetarian\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"no problem with extra spaces\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\";\",\";\",\";\",\";-\",\"function myfunc, var1\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.62.docs-return-not-needed.spec.ts":"{\"suiteName\":\"Detects when the returns tag is present for procedures\",\"fileName\":\"code.62.docs-return-not-needed.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\";-\",\"pro myroutine, var1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem\",\"code\":[\";+\",\"; :Params:\",\"; var1: in, optional, boolean, public\",\"; My favorite argument\",\"; :Returns: number\",\";-\",\"pro myroutine, var1\",\" compile_opt idl2\",\"end\"]}]}","code.63.docs-not-real-param.spec.ts":"{\"suiteName\":\"Detects when a documented parameter does not exist in routine definition\",\"fileName\":\"code.63.docs-not-real-param.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem with args and keywords\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, var2, KW1=kw1, KW2=kw2\",\" compile_opt idl2\",\"end\"]},{\"name\":\"do not mistake colons in the description as parameters\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing: something else\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag: something else\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"detect in structures\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: any\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]}]}","code.64.pdocs-param-missing.spec.ts":"{\"suiteName\":\"Detects when a defined parameter is missing from user docs\",\"fileName\":\"code.64.pdocs-param-missing.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problem with args and keywords\",\"code\":[\";+\",\"; My procedure\",\";\",\"; :Args:\",\";\",\"; :Keywords:\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\"end\"]}]}","code.65.string-literal-too-many-args.spec.ts":"{\"suiteName\":\"Detects when a string literal has too many arguments\",\"fileName\":\"code.65.string-literal-too-many-args.spec.ts\",\"tests\":[{\"name\":\"no problems\",\"code\":\"`${1.234,\\\"%10.3f\\\"}`\"},{\"name\":\"no problems - string literal in formatting\",\"code\":\"`${1.234,`%${w}.3f`}`\"},{\"name\":\"problem with too many args\",\"code\":\"`${1.234,abc,\\\"%10.3f\\\"}`\"}]}","code.66.bad-continue.spec.ts":"{\"suiteName\":\"Detects bad continue statements\",\"fileName\":\"code.66.bad-continue.spec.ts\",\"tests\":[{\"name\":\"no problems in loops\",\"code\":[\"compile_opt idl2\",\"for i=0,10 do if !true then continue\",\"foreach val, key do if !true then continue\",\"while !true do if !false then continue\",\"repeat if !true then continue until !true\",\"end\"]},{\"name\":\"problems outside of loops\",\"code\":[\"compile_opt idl2\",\"continue\",\"end\"]}]}","code.67.bad-break.spec.ts":"{\"suiteName\":\"Detects bad break statements\",\"fileName\":\"code.67.bad-break.spec.ts\",\"tests\":[{\"name\":\"no problems in loops\",\"code\":[\"compile_opt idl2\",\"for i=0,10 do if !true then break\",\"foreach val, key do if !true then break\",\"while !true do if !false then break\",\"repeat if !true then break until !true\",\"end\"]},{\"name\":\"no problems in switch\",\"code\":[\"compile_opt idl2\",\"switch a of\",\" !true: break\",\"endswitch\",\"end\"]},{\"name\":\"no problems in case\",\"code\":[\"compile_opt idl2\",\"case a of\",\" !true: break\",\"endcase\",\"end\"]},{\"name\":\"problems outside of loops\",\"code\":[\"compile_opt idl2\",\"break\",\"end\"]}]}","code.68.expected-statement.spec.ts":"{\"suiteName\":\"Detects tokens that are empty but shouldn't be\",\"fileName\":\"code.68.expected-statement.spec.ts\",\"tests\":[{\"name\":\"problem in assignment\",\"code\":[\"compile_opt idl2\",\"a = \",\"end\"]},{\"name\":\"problem in basic operators\",\"code\":[\"compile_opt idl2\",\"a = 42 +\",\"end\"]},{\"name\":\"problem in compound operator\",\"code\":[\"compile_opt idl2\",\"a *= \",\"end\"]},{\"name\":\"problem in logical operator\",\"code\":[\"compile_opt idl2\",\"a = 5 and \",\"end\"]},{\"name\":\"problem in negative sign\",\"code\":[\"compile_opt idl2\",\"a = - \",\"end\"]},{\"name\":\"problem in pointer dereference\",\"code\":[\"compile_opt idl2\",\"a = *\",\"end\"]},{\"name\":\"problem in parentheses\",\"code\":[\"compile_opt idl2\",\"a = ()\",\"end\"]},{\"name\":\"problem in for\",\"code\":[\"compile_opt idl2\",\"for\",\"end\"]},{\"name\":\"problem in foreach\",\"code\":[\"compile_opt idl2\",\"foreach\",\"end\"]},{\"name\":\"problem in foreach\",\"code\":[\"compile_opt idl2\",\"while\",\"end\"]},{\"name\":\"problem in foreach\",\"code\":[\"compile_opt idl2\",\"for i=0,1 do\",\"end\"]},{\"name\":\"problem in repeat\",\"code\":[\"compile_opt idl2\",\"repeat\",\"end\"]},{\"name\":\"problem in until\",\"code\":[\"compile_opt idl2\",\"repeat a = 5 until\",\"end\"]},{\"name\":\"problem in if\",\"code\":[\"compile_opt idl2\",\"if\",\"end\"]},{\"name\":\"problem in then\",\"code\":[\"compile_opt idl2\",\"if !true then\",\"end\"]},{\"name\":\"problem in else\",\"code\":[\"compile_opt idl2\",\"if !true then a = 42 else\",\"end\"]},{\"name\":\"problem in ternary then\",\"code\":[\"compile_opt idl2\",\"a = !true ?\",\"end\"]},{\"name\":\"problem in ternary else\",\"code\":[\"compile_opt idl2\",\"a = !true ? 42 :\",\"end\"]},{\"name\":\"problem in switch\",\"code\":[\"compile_opt idl2\",\"switch\",\"end\"]},{\"name\":\"problem in case\",\"code\":[\"compile_opt idl2\",\"case\",\"end\"]},{\"name\":\"problem in of for switch\",\"code\":[\"compile_opt idl2\",\"switch !true of\",\"end\"]},{\"name\":\"problem in of for case\",\"code\":[\"compile_opt idl2\",\"switch !true of\",\"end\"]}]}","code.69.unfinished-dot.spec.ts":"{\"suiteName\":\"Detects tokens that are empty but shouldn't be\",\"fileName\":\"code.69.unfinished-dot.spec.ts\",\"tests\":[{\"name\":\"as procedure-method or property access, but incomplete\",\"code\":[\"compile_opt idl2\",\"a.\",\"end\"]},{\"name\":\"as function method or property access, but incomplete\",\"code\":[\"compile_opt idl2\",\"a = b.\",\"end\"]},{\"name\":\"standalone 1\",\"code\":[\"compile_opt idl2\",\"a = .\",\"end\"]},{\"name\":\"standalone 2\",\"code\":[\"compile_opt idl2\",\".\",\"end\"]}]}","code.70.illegal-hex-escape.spec.ts":"{\"suiteName\":\"Verify string literal escape characters\",\"fileName\":\"code.70.illegal-hex-escape.spec.ts\",\"tests\":[{\"name\":\"only have a problem with the last one\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"end\"]}]}","code.71.unknown-template-escape.spec.ts":"{\"suiteName\":\"Find unknown string literal escape characters\",\"fileName\":\"code.71.unknown-template-escape.spec.ts\",\"tests\":[{\"name\":\"no problems with all good\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00`\",\"end\"]},{\"name\":\"problems with incomplete and bad ones\",\"code\":[\"compile_opt idl2\",\"a = `\\\\ `\",\"a = `\\\\a`\",\"a = `\\\\42`\",\"a = `\\\\lark \\\\r\\\\n`\",\"end\"]}]}","code.72.duplicate-arg-kw-var-def.spec.ts":"{\"suiteName\":\"Find duplicate arg and keyword variables and detect\",\"fileName\":\"code.72.duplicate-arg-kw-var-def.spec.ts\",\"tests\":[{\"name\":\"no problems when OK\",\"code\":[\"pro mypro, a, b, AKW = akw, BKW = bkw\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in procedures\",\"code\":[\"pro mypro, a, a, b, B = b, C = b\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in procedure methods\",\"code\":[\"pro myclass::mymethod, a, a, b, B = b, C = b\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in functions\",\"code\":[\"function myfunc, a, a, b, B = b, C = b\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problems in function methods\",\"code\":[\"function myclass::mymethod, a, a, b, B = b, C = b\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.73.duplicate-kw-def.spec.ts":"{\"suiteName\":\"Find duplicate keyword definitions\",\"fileName\":\"code.73.duplicate-kw-def.spec.ts\",\"tests\":[{\"name\":\"no problems when OK\",\"code\":[\"pro mypro, AKW = akw, BKW = bkw\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in procedures\",\"code\":[\"pro mypro, AKW = akw, AKW = bkw\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in procedure methods\",\"code\":[\"pro myclass::mypro, AKW = akw, AKW = bkw\",\" compile_opt idl2\",\"end\"]},{\"name\":\"problems in functions\",\"code\":[\"function myfunc, AKW = akw, AKW = bkw\",\" compile_opt idl2\",\" return, 1\",\"end\"]},{\"name\":\"problems in function methods\",\"code\":[\"function myfunc::mymethod, AKW = akw, AKW = bkw\",\" compile_opt idl2\",\" return, 1\",\"end\"]}]}","code.74.duplicate-property.spec.ts":"{\"suiteName\":\"Find duplicate properties and find\",\"fileName\":\"code.74.duplicate-property.spec.ts\",\"tests\":[{\"name\":\"no problems when OK\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a = {a:a, B :b}\",\"end\"]},{\"name\":\"problems when we have them\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a = {a:a, A :b}\",\"end\"]}]}","code.75.duplicate-kw-usage.spec.ts":"{\"suiteName\":\"Find keyword usage and detect problems in\",\"fileName\":\"code.75.duplicate-kw-usage.spec.ts\",\"tests\":[{\"name\":\"procedures\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"plot, kw1=5, KW1=5, kw1=5, /KW1\",\"end\"]},{\"name\":\"procedure methods\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a.plot, kw1=5, KW1=5, kw1=5, /KW1\",\"end\"]},{\"name\":\"functions\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a = plot(kw1=5, KW1=5, kw1=5, /KW1)\",\"end\"]},{\"name\":\"function methods\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"a = b.plot(kw1=5, KW1=5, kw1=5, /KW1)\",\"end\"]}]}","code.76.init-method-pro.spec.ts":"{\"suiteName\":\"Check for init methods\",\"fileName\":\"code.76.init-method-pro.spec.ts\",\"tests\":[{\"name\":\"being procedures incorrectly\",\"code\":[\"pro mypro::init\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.77.unknown-structure.spec.ts":"{\"suiteName\":\"Check for structure names\",\"fileName\":\"code.77.unknown-structure.spec.ts\",\"tests\":[{\"name\":\"reported not in class definitions\",\"code\":[\"pro auto_doc_example\",\" compile_opt idl2\",\" a = {ENVIRaster2}\",\"end\"]},{\"name\":\"ignored in class definitions\",\"code\":[\"pro auto_doc_example__define\",\" compile_opt idl2\",\" a = {ENVIRaster2}\",\"end\"]}]}","code.78.illegal-chain.spec.ts":"{\"suiteName\":\"Check for bad access\",\"fileName\":\"code.78.illegal-chain.spec.ts\",\"tests\":[{\"name\":\"from function calls\",\"code\":[\"pro so_bad\",\" compile_opt idl2\",\" a = myfunc().ohNo\",\" a = myfunc().(42)\",\" myfunc().ohMeOhMy\",\" a = myfunc().ohNotOk()\",\"end\"]},{\"name\":\"from function method calls\",\"code\":[\"pro so_sad\",\" compile_opt idl2\",\" a = var.myfunc().ohNo\",\" a = var.myfunc().(42)\",\" var.myfunc().ohMeOhMy\",\" a = var.myfunc().ohNotOk()\",\"end\"]}]}","code.79.docs-missing-struct.spec.ts":"{\"suiteName\":\"Check for missing structure definitions\",\"fileName\":\"code.79.docs-missing-struct.spec.ts\",\"tests\":[{\"name\":\"from docs 1\",\"code\":[\";+\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]},{\"name\":\"from docs 2\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: any\",\"; Placeholder docs for argument or keyword\",\"; prop2:any\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]},{\"name\":\"ignore when no docs\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]},{\"name\":\"ignore when just procedure\",\"code\":[\";+\",\";-\",\"pro pro4\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]},{\"name\":\"ignore when function\",\"code\":[\"function myfunc\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" return, 1\",\"end\"]}]}","code.80.docs-missing-prop.spec.ts":"{\"suiteName\":\"Check for missing properties\",\"fileName\":\"code.80.docs-missing-prop.spec.ts\",\"tests\":[{\"name\":\"in our docs\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: any\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]}]}","code.81.class-no-params.spec.ts":"{\"suiteName\":\"Check for args and keywords in procedure class definitions\",\"fileName\":\"code.81.class-no-params.spec.ts\",\"tests\":[{\"name\":\"with arg\",\"code\":[\"pro pro4__define, a\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"with kw\",\"code\":[\"pro pro4__define, KW = kw\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"with both\",\"code\":[\"pro pro4__define, arg, KW = kw\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"ok with neither\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\"end\"]}]}","code.82.docs-prop-too-few-params.spec.ts":"{\"suiteName\":\"Not enough parameters for properties\",\"fileName\":\"code.82.docs-prop-too-few-params.spec.ts\",\"tests\":[{\"name\":\"without anything\",\"code\":[\";+\",\"; :NYStruct0:\",\"; prop1:\",\"; Placeholder docs for argument, keyword, or property\",\";\",\"; :NYStruct:\",\"; prop2: \",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3__define\",\" compile_opt idl3\",\"\",\" !null = {NYStruct0, prop1: 5}\",\"\",\" !null = {NYStruct, inherits NYStruct0, prop2: 6}\",\"end\"]},{\"name\":\"no problems\",\"code\":[\";+\",\"; :NYStruct0:\",\"; prop1: any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\"; :NYStruct:\",\"; prop2: String | number\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3__define\",\" compile_opt idl3\",\"\",\" !null = {NYStruct0, prop1: 5}\",\"\",\" !null = {NYStruct, inherits NYStruct0, prop2: 6}\",\"end\"]}]}","code.83.docs-prop-too-many-params.spec.ts":"{\"suiteName\":\"Too many parameters for properties\",\"fileName\":\"code.83.docs-prop-too-many-params.spec.ts\",\"tests\":[{\"name\":\"with extra\",\"code\":[\";+\",\"; :NYStruct0:\",\"; prop1: any, bad\",\"; Placeholder docs for argument, keyword, or property\",\";\",\"; :NYStruct:\",\"; prop2: String, noop\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3__define\",\" compile_opt idl3\",\"\",\" !null = {NYStruct0, prop1: 5}\",\"\",\" !null = {NYStruct, inherits NYStruct0, prop2: 6}\",\"end\"]},{\"name\":\"no problems\",\"code\":[\";+\",\"; :NYStruct0:\",\"; prop1: Hash\",\"; Placeholder docs for argument, keyword, or property\",\";\",\"; :NYStruct:\",\"; prop2: String\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3__define\",\" compile_opt idl3\",\"\",\" !null = {NYStruct0, prop1: 5}\",\"\",\" !null = {NYStruct, inherits NYStruct0, prop2: 6}\",\"end\"]}]}","code.84.illegal-subscript.spec.ts":"{\"suiteName\":\"Illegal subscript\",\"fileName\":\"code.84.illegal-subscript.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Dictionary\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro index_problems, arg1, arg2, arg3, arg4, arg5\",\" compile_opt idl3\",\"\",\" ; for arrays\",\" a1 = arg1[*]\",\" a2 = arg1[0, 1, *]\",\" a3 = arg1[0, 1, 2]\",\" a4 = arg1[0 : -1 : 1]\",\" a5 = arg1[0, 1, *]\",\"\",\" ; for lists\",\" l1 = arg2[*]\",\" l2 = arg2[0, 1, *]\",\" l3 = arg2[0, 1, 2]\",\" l4 = arg2[0 : -1 : 1]\",\" l5 = arg2[0, 1, *]\",\"\",\" ; for hashes\",\" h1 = arg3[*]\",\" h2 = arg3[0, 1, *]\",\" h3 = arg3[0, 1, 2]\",\" h4 = arg3[0 : -1 : 1]\",\" h5 = arg3[0, 1, *]\",\"\",\" ; for ordered hashes\",\" oh1 = arg4[*]\",\" oh2 = arg4[0, 1, *]\",\" oh3 = arg4[0, 1, 2]\",\" oh4 = arg4[0 : -1 : 1]\",\" oh5 = arg4[0, 1, *]\",\"\",\" ; for dictionaries\",\" d1 = arg5[*]\",\" d2 = arg5[0, 1, *]\",\" d3 = arg5[0, 1, 2]\",\" d3 = arg5[0 : -1 : 1]\",\" d5 = arg5[0, 1, *]\",\"end\"]}]}","code.85.illegal-struct-op.spec.ts":"{\"suiteName\":\"Illegal structure\",\"fileName\":\"code.85.illegal-struct-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro struct_checks\",\"compile_opt idl2\",\"\",\"str = {a: 42}\",\"\",\"a = 1 + str\",\"\",\"b = str + {a: 42}\",\"\",\"c = str + list()\",\"\",\"d = str + hash()\",\"\",\"e = str + orderedhash()\",\"\",\"f = str + dictionary()\",\"end\"]}]}","code.86.illegal-list-op.spec.ts":"{\"suiteName\":\"Illegal list\",\"fileName\":\"code.86.illegal-list-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro list_checks\",\"compile_opt idl2\",\"\",\"a = 1 + list()\",\"\",\"b = list() + list()\",\"\",\"c = list() + hash()\",\"\",\"d = list() + orderedhash()\",\"\",\"e = list() + dictionary()\",\"end\"]}]}","code.87.illegal-hash-op.spec.ts":"{\"suiteName\":\"Illegal hash\",\"fileName\":\"code.87.illegal-hash-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro hash_checks\",\"compile_opt idl2\",\"\",\"a = 1 + hash()\",\"\",\"b = hash() + list()\",\"\",\"c = hash() + hash()\",\"\",\"d = hash() + orderedhash()\",\"\",\"e = hash() + dictionary()\",\"end\"]}]}","code.88.illegal-ordered-hash-op.spec.ts":"{\"suiteName\":\"Illegal ordered hash\",\"fileName\":\"code.88.illegal-ordered-hash-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro orderedhash_checks\",\"compile_opt idl2\",\"\",\"a = 1 + orderedhash()\",\"\",\"b = orderedhash() + list()\",\"\",\"c = orderedhash() + hash()\",\"\",\"d = orderedhash() + orderedhash()\",\"\",\"e = orderedhash() + dictionary()\",\"end\"]}]}","code.89.illegal-dictionary-op.spec.ts":"{\"suiteName\":\"Illegal dictionary\",\"fileName\":\"code.89.illegal-dictionary-op.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro dictionary_checks\",\"compile_opt idl2\",\"\",\"a = 1 + dictionary()\",\"\",\"b = dictionary() + list()\",\"\",\"c = dictionary() + hash()\",\"\",\"d = dictionary() + orderedhash()\",\"\",\"e = dictionary() + dictionary()\",\"end\"]}]}","code.90.potential-type-incompatibility.spec.ts":"{\"suiteName\":\"Potential type incompatibility in\",\"fileName\":\"code.90.potential-type-incompatibility.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\"pro incompatible_checks\",\"compile_opt idl2\",\"\",\"a = 1 + ENVIRaster()\",\"\",\"b = 1 + plot()\",\"end\"]},{\"name\":\"no problems with array creation\",\"code\":[\"pro incompatible_checks\",\"compile_opt idl2\",\"\",\"arr1 = [ENVIRaster(), ENVIMetaspectralRaster(), ENVISubsetRaster()]\",\"arr2 = [{}, {}]\",\"end\"]},{\"name\":\"problems with array creation\",\"code\":[\"pro incompatible_checks\",\"compile_opt idl2\",\"\",\"bad1 = [ENVIRaster(), {}]\",\"bad2 = [{}, 1]\",\"end\"]}]}","code.91.illegal-index-type.spec.ts":"{\"suiteName\":\"Illegal index checks for\",\"fileName\":\"code.91.illegal-index-type.spec.ts\",\"tests\":[{\"name\":\"all types\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Dictionary\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro index_problems, arg1, arg2, arg3, arg4, arg5\",\" compile_opt idl3\",\"\",\" ; for arrays\",\" !null = arg1[plot()]\",\" !null = arg1[1j]\",\" !null = arg1[1i]\",\" !null = arg1[1di]\",\" !null = arg1[1dj]\",\"\",\" ; for lists\",\" !null = arg2[plot()]\",\" !null = arg2[1j]\",\" !null = arg2[1i]\",\" !null = arg2[1di]\",\" !null = arg2[1dj]\",\"\",\" ; for hashes\",\" !null = arg3[plot()]\",\" !null = arg3[1j]\",\" !null = arg3[1i]\",\" !null = arg3[1di]\",\" !null = arg3[1dj]\",\"\",\" ; for ordered hashes\",\" !null = arg4[plot()]\",\" !null = arg4[1j]\",\" !null = arg4[1i]\",\" !null = arg4[1di]\",\" !null = arg4[1dj]\",\"\",\" ; for dictionaries\",\" !null = arg5[plot()]\",\" !null = arg5[1j]\",\" !null = arg5[1i]\",\" !null = arg5[1di]\",\" !null = arg5[1dj]\",\"end\"]},{\"name\":\"allow boolean since it is really a number\",\"code\":[\"pro index_problems\",\" compile_opt idl2\",\"\",\" ; for arrays\",\" display = strarr(c)\",\" i = keyword_set(!null)\",\" !null = display[i]\",\"end\"]}]}","code.92.potential-arr-type-incompatibility.spec.ts":"{\"suiteName\":\"Array data type incompatibility\",\"fileName\":\"code.92.potential-arr-type-incompatibility.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro array_incompatibility, arg1, arg4, arg5\",\" compile_opt idl2\",\"\",\" ; OK\",\" a = arg1 + arg4\",\"\",\" ; bad\",\" b = arg1 + arg4 + arg5\",\"end\"]}]}","code.93.ptr-nothing-to-de-ref.spec.ts":"{\"suiteName\":\"De-referencing noting\",\"fileName\":\"code.93.ptr-nothing-to-de-ref.spec.ts\",\"tests\":[{\"name\":\"with asterisks\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\"\",\" ; yikes\",\" a = *\",\"\",\" ; bad\",\" b = (*)\",\"end\"]}]}","code.94.ptr-de-ref-illegal.spec.ts":"{\"suiteName\":\"Pointer de-ref without pointers\",\"fileName\":\"code.94.ptr-de-ref-illegal.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Pointer | String\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, Pointer | Pointer\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pointers, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; number\",\" a = *arg1\",\"\",\" ; enviraster\",\" b = *arg3[0]\",\"\",\" ; any, unable to de-reference\",\" d = *5\",\"\",\" ; any\",\" f = *arg5\",\"\",\" ; union of type args\",\" g = *arg6\",\"end\"]}]}","code.95.indexing-error.spec.ts":"{\"suiteName\":\"Errors for indexing\",\"fileName\":\"code.95.indexing-error.spec.ts\",\"tests\":[{\"name\":\"variables that cannot be indexed\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Arguments:\",\"; a: in, required, Number\",\"; Placeholder docs for argument, keyword, or property\",\"; b: in, required, ComplexNumber\",\"; Placeholder docs for argument, keyword, or property\",\"; c: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; d: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\"; e: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; f: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\"; g: in, required, Dictionary\",\"; Placeholder docs for argument, keyword, or property\",\"; h: in, required, ENVIRasterMetadata\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function allowed_to_index, a, b, c, d, e, f, g, h\",\" compile_opt idl2\",\"\",\" ; OK\",\" !null = c[0]\",\" !null = d[0]\",\" !null = e[0]\",\" !null = f[0]\",\" !null = g[0]\",\"\",\" ; also OK, though non standard IDL types\",\" !null = h[0]\",\"\",\" ; problems\",\" byte = ('s' + 1b)[0]\",\" int = ('s' + 1s)[0]\",\" uint = ('s' + 1us)[0]\",\" long = ('s' + 1l)[0]\",\" ulong = ('s' + 1ul)[0]\",\" long64 = ('s' + 1ll)[0]\",\" ulong64 = ('s' + 1ull)[0]\",\" float1 = ('s' + 1.)[0]\",\" float2 = ('s' + 1e)[0]\",\" double = ('s' + 1d)[0]\",\" biginteger = ('s' + BigInteger(5))[0]\",\" number = ('s' + a)[0]\",\" complexfloat = ('s' + 1.i)[0]\",\" complexdouble = ('s' + 1di)[0]\",\" complexdouble = ('s' + 1dj)[0]\",\" complexnumber1 = ('s' + a + 1di + 1dj)[0]\",\" complexnumber2 = (a + b)[0]\",\"\",\" return, 1\",\"end\"]}]}","code.96.ptr-de-ref-ambiguity.spec.ts":"{\"suiteName\":\"Pointer de-ref without pointers\",\"fileName\":\"code.96.ptr-de-ref-ambiguity.spec.ts\",\"tests\":[{\"name\":\"operations\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Pointer | String\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, Pointer | Pointer\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pointers, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; number\",\" a = *arg1\",\"\",\" ; enviraster\",\" b = *arg3[0]\",\"\",\" ; ambiguous\",\" c = *arg4\",\"\",\" ; any\",\" f = *arg5\",\"\",\" ; union of type args\",\" g = *arg6\",\"end\"]}]}","code.97.unknown-kw.spec.ts":"{\"suiteName\":\"Check for known keywords\",\"fileName\":\"code.97.unknown-kw.spec.ts\",\"tests\":[{\"name\":\"and report errors if we dont have \\\"_extra\\\" or \\\"_ref_extra\\\"\",\"code\":[\";+\",\"; :Description:\",\"; Constructor\",\";\",\"; :Returns:\",\"; myclass\",\";\",\";-\",\"function myclass::Init\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw: out, optional, Array\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myclass::method, kw = kw, _ref_extra = _extra\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw: out, optional, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro myclass::method, kw = kw, _extra = _extra\",\" compile_opt idl2\",\"end\",\"\",\";+\",\"; :Description:\",\"; Class definition procedure\",\";\",\";-\",\"pro myclass__define\",\" compile_opt idl2\",\"\",\" struct = {myclass}\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw: out, optional, Long\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myfunc, kw = kw\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw: out, optional, Byte\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro mypro, kw = kw\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main level program\",\"compile_opt idl2\",\"\",\"; procedures\",\"mypro, kw = a, /kw2, kw3 = 3\",\"\",\"; functions\",\"!null = myfunc(kw = b, /kw2, kw3 = 3)\",\"\",\"; make class for methods\",\"var = myclass()\",\"\",\"; procedure methods\",\"var.method, kw = c, /kw2, kw3 = 3\",\"\",\"; function methods\",\"!null = var.method(kw = d, /kw2, kw3 = 3)\",\"end\"]}]}","code.97.unknown-kw.exceptions.spec.ts":"{\"suiteName\":\"Check for known keywords\",\"fileName\":\"code.97.unknown-kw.exceptions.spec.ts\",\"tests\":[{\"name\":\"and exclude these cases\",\"code\":[\"; main level program\",\"compile_opt idl2\",\"\",\"; procedures\",\"p = plot(/tes)\",\"end\"]},{\"name\":\"unless we have extra or ref extra (only one at a time)\",\"code\":[\";+\",\"; :Keywords:\",\"; _ref_extra: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro auto_doc_example2, _ref_extra = ex\",\" compile_opt idl2\",\"\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; _extra: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro auto_doc_example, _extra = ex\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main\",\"compile_opt idl2\",\"\",\"; OK with only extra\",\"auto_doc_example, /anything_i_want\",\"\",\"; OK with only ref extra\",\"auto_doc_example2, /anything_i_want\",\"\",\"end\"]}]}","code.97.unknown-kw.exceptions2.spec.ts":"{\"suiteName\":\"Check for known keywords\",\"fileName\":\"code.97.unknown-kw.exceptions2.spec.ts\",\"tests\":[{\"name\":\"but always ignore extra and strict extra\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function auto_doc_example\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main\",\"compile_opt idl2\",\"\",\"; no error\",\"a = auto_doc_example(_extra = !null)\",\"\",\"; no error\",\"a = auto_doc_example(_strict_extra = !null)\",\"\",\"end\"]}]}","code.97.unknown-kw.exceptions3.spec.ts":"{\"suiteName\":\"Check for known keywords\",\"fileName\":\"code.97.unknown-kw.exceptions3.spec.ts\",\"tests\":[{\"name\":\"but always obj_new\",\"code\":[\"; main\",\"compile_opt idl2\",\"\",\"; no error\",\"outClass = 'something'\",\"!null = OBJ_NEW(outClass, FOLD_CASE=!null))\",\"\",\"end\"]}]}","code.98.incomplete-ternary.spec.ts":"{\"suiteName\":\"Check for incomplete ternary\",\"fileName\":\"code.98.incomplete-ternary.spec.ts\",\"tests\":[{\"name\":\"operators missing the second half\",\"code\":[\"compile_opt idl2\",\"; wrong\",\"a = !true ? 5\",\"\",\"; right\",\"!null = !true ? 5 : 'yeah'\",\"\",\"; right\",\"!null = !true ? (5) : 'yeah'\",\"\",\"end\"]}]}","code.99.undefined-var.spec.ts":"{\"suiteName\":\"Detect undefined variables\",\"fileName\":\"code.99.undefined-var.spec.ts\",\"tests\":[{\"name\":\"in most places\",\"code\":[\";+\",\"; :Arguments:\",\"; a: in, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\"; b: out, required, Long\",\"; Placeholder docs for argument, keyword, or property\",\"; c: out, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro undefined_without_common, a, b, c\",\" compile_opt idl2\",\"\",\" ; direct vars\",\" test1 = bad\",\"\",\" ; within child branches\",\" test2 = (ok = 5) + wrong\",\"\",\" ; as keyword\",\" test3 = ENVIRaster(metadata = meta) ; formatting matches docs\",\"\",\" ; OK\",\" for i = 0, 100 do begin\",\" !null = i\",\" endfor\",\"\",\" ; item is bad\",\" foreach val, item, key do begin\",\" !null = val\",\" !null = key\",\" endforeach\",\"\",\" ; noBueno is bad\",\" noBueno->method\",\"end\"]},{\"name\":\"never define self\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function dataToMemoryRaster\",\" compile_opt idl2\",\"\",\" ; should error\",\" self = 5\",\"\",\" ; should error\",\" a = self\",\"\",\" return, 1\",\"end\"]},{\"name\":\"define self in methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::mymethod\",\" compile_opt idl2\",\"\",\" ; no error\",\" self = 5\",\"\",\" ; no error\",\" a = self\",\"\",\" return, 1\",\"end\"]},{\"name\":\"catc\",\"code\":[\"compile_opt idl2\",\"filename = filepath('qb_boulder_msi', root = nv.root_dir)\",\"end\"]}]}","code.99.undefined-var.edge-cases.spec.ts":"{\"suiteName\":\"Check unknown variables in edge cases\",\"fileName\":\"code.99.undefined-var.edge-cases.spec.ts\",\"tests\":[{\"name\":\"in keywords\",\"code\":[\"compile_opt idl2\",\"filename = filepath('qb_boulder_msi', root = nv.root_dir)\",\"end\"]},{\"name\":\"pointer value assignment\",\"code\":[\"compile_opt idl2\",\"*other = 42\",\"end\"]}]}","code.99.undefined-var.exceptions1.spec.ts":"{\"suiteName\":\"Don't check unknown keywords\",\"fileName\":\"code.99.undefined-var.exceptions1.spec.ts\",\"tests\":[{\"name\":\"in in methods that we dont know\",\"code\":[\" compile_opt idl2\",\"l = luna(/in_package)\",\"(l.expects(routine)).toRunFunction, raster, _output = output\",\"end\"]},{\"name\":\"verify we process parents before children\",\"code\":[\" compile_opt idl2\",\" item = list()\",\" ; item is bad\",\" foreach val, item, key do begin\",\" val = 5\",\" endforeach\",\"end\"]}]}","code.99.undefined-var.exceptions2.spec.ts":"{\"suiteName\":\"Without docs, keywords are least restrictive\",\"fileName\":\"code.99.undefined-var.exceptions2.spec.ts\",\"tests\":[{\"name\":\"and bidirectional\",\"code\":[\"pro unknown_kw_relaxed, kw = kw\",\"compile_opt idl2\",\"end\",\"\",\"; main\",\"compile_opt idl2\",\"unknown_kw_relaxed, kw = newVar\",\"end\"]}]}","code.99.undefined-var.exceptions3.spec.ts":"{\"suiteName\":\"Without known global, arguments are least restrictive\",\"fileName\":\"code.99.undefined-var.exceptions3.spec.ts\",\"tests\":[{\"name\":\"and bidirectional\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Arguments:\",\"; data: bidirectional, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function dataToMemoryRaster, data\",\" compile_opt idl2, hidden\",\"\",\" ; make everything\",\" oSvc = obj_new('IDLcfSvcOpenMemoryRaster') ; IDLcfSvcOpenMemoryRaster()\",\" ok = oSvc.Open(memory_data = data, '', oRaster, data_type = data.typecode)\",\" ok = IDLcfGetServiceObject(!null, 'ManageRaster', oManageRaster)\",\" void = oManageRaster.ManageBands(oRaster)\",\"\",\" ; return our raster\",\" return, ENVIWrapComponent(oRaster)\",\"end\"]}]}","code.99.undefined-var.exceptions4.spec.ts":"{\"suiteName\":\"Keyword variables should be defined\",\"fileName\":\"code.99.undefined-var.exceptions4.spec.ts\",\"tests\":[{\"name\":\"and not report errors\",\"code\":[\"function bridge_it::Init, nbridges, init = init, msg = msg, logdir = logdir, nrefresh = nrefresh, prefix = prefix\",\"compile_opt idl2, hidden\",\"\",\"; check to see if different messag eneeds to be used\",\"if ~keyword_set(msg) then self.msg = 'Time to complete bridge process (sec): ' else self.msg = msg\",\"\",\"; check to see if we have a number of processes to complete before refreshing the bridges\",\"; otherwise set the refresh number to an absurbly high result!\",\"if keyword_set(nrefresh) then self.nrefresh = nrefresh else self.nrefresh = 1000000l\",\"\",\"; check if init keyword is set, if so then we want to save the init string\",\"if keyword_set(init) then self.init = strjoin(init, ' & ')\",\"\",\"; check if logdir is specified\",\"if keyword_set(logdir) then begin\",\" if file_test(logdir) then begin\",\" self.logdir = logdir\",\" endif else begin\",\" message, 'Specified LOGDIR does not exist!'\",\" endelse\",\"endif\",\"\",\"return, 1\",\"end\"]}]}","code.99.undefined-var.exceptions5.spec.ts":"{\"suiteName\":\"With lambda functions\",\"fileName\":\"code.99.undefined-var.exceptions5.spec.ts\",\"tests\":[{\"name\":\"do not extract or check variables\",\"code\":[\"; main level\",\"compile_opt idl2\",\"!null = lambda(n:n le 3 || min(n mod [2:fix(sqrt(n))]))\",\"end\"]}]}","code.99.undefined-var.exceptions6.spec.ts":"{\"suiteName\":\"With common blocks\",\"fileName\":\"code.99.undefined-var.exceptions6.spec.ts\",\"tests\":[{\"name\":\"skip the name of the common block\",\"code\":[\"; main level\",\"compile_opt idl2\",\"common theName, a1, bb, cc\",\"end\"]}]}","code.100.potential-undefined-var.spec.ts":"{\"suiteName\":\"Detect undefined variables\",\"fileName\":\"code.100.potential-undefined-var.spec.ts\",\"tests\":[{\"name\":\"when we have a common block present\",\"code\":[\";+\",\"; :Arguments:\",\"; a: in, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\"; b: out, required, Long\",\"; Placeholder docs for argument, keyword, or property\",\"; c: out, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro undefined_with_common, a, b, c\",\" compile_opt idl2\",\" common\",\"\",\" ; direct vars\",\" test1 = bad\",\"\",\" ; within child branches\",\" test2 = (ok = 5) + wrong\",\"\",\" ; as keyword\",\" test3 = ENVIRaster(metadata = meta) ; formatting matches docs\",\"\",\" ; OK\",\" for i = 0, 100 do begin\",\" !null = i\",\" endfor\",\"\",\" ; item is bad\",\" foreach val, item, key do begin\",\" !null = val\",\" !null = key\",\" endforeach\",\"\",\" ; noBueno is bad\",\" noBueno->method\",\"end\"]},{\"name\":\"dont add a var for the first child of a common block\",\"code\":[\"pro color_edit_back\",\"compile_opt idl2\",\"\",\"common color_edit, wxsize, wysize, r0\",\"\",\"for i = wysize - 60, wysize - 30 do tv, ramp, wxsize / 2 - 256, i\",\"\",\"cx = wxsize / 4.\",\"cy = wysize - 90. - r0\",\"\",\"a = color_edit\",\"\",\"return\",\"end\"]}]}","code.101.var-use-before-def.spec.ts":"{\"suiteName\":\"Use variable before it is defined\",\"fileName\":\"code.101.var-use-before-def.spec.ts\",\"tests\":[{\"name\":\"when we dont have a common-block present\",\"code\":[\"pro before_defined_no_common\",\"compile_opt idl2\",\"\",\"; problemo\",\"a = b\",\"\",\"; define\",\"b = 5\",\"\",\"; complex problem0\",\"c = d + (d = 5)\",\"\",\"; no problemo\",\"f = (g = 6) + g\",\"end\"]}]}","code.101.var-use-before-def.exceptions.spec.ts":"{\"suiteName\":\"Use variable before it is defined\",\"fileName\":\"code.101.var-use-before-def.exceptions.spec.ts\",\"tests\":[{\"name\":\"does not trigger anywhere\",\"code\":[\"function ReadExif::_GetName, tag, image = img, photo = pht, gps = gps, iop = iop\",\"compile_opt idl2, hidden\",\"\",\"name = ''\",\"img = keyword_set(img)\",\"pht = keyword_set(pht)\",\"gps = keyword_set(gps)\",\"iop = keyword_set(iop)\",\"\",\"; if none are set, default to all\",\"if (array_equal([img, pht, gps, iop], 0)) then begin\",\" img = (pht = (gps = (iop = 1)))\",\"endif\",\"\",\"if (iop) then begin\",\" if (self.ioptags.HasKey(tag)) then begin\",\" name = self.ioptags[tag]\",\" endif\",\"endif\",\"\",\"if (gps) then begin\",\" if (self.gpstags.HasKey(tag)) then begin\",\" name = self.gpstags[tag]\",\" endif\",\"endif\",\"\",\"if (pht) then begin\",\" if (self.phototags.HasKey(tag)) then begin\",\" name = self.phototags[tag]\",\" endif\",\"endif\",\"\",\"if (img) then begin\",\" if (self.imagetags.HasKey(tag)) then begin\",\" name = self.imagetags[tag]\",\" endif\",\"endif\",\"\",\"return, name\",\"end\"]}]}","code.102.potential-var-use-before-def.spec.ts":"{\"suiteName\":\"Use variable before it is defined\",\"fileName\":\"code.102.potential-var-use-before-def.spec.ts\",\"tests\":[{\"name\":\"when we dont have a common-block present\",\"code\":[\"pro before_defined_common\",\"compile_opt idl2\",\"common\",\"\",\"; problemo\",\"a = b\",\"\",\"; define\",\"b = 5\",\"\",\"; complex problem0\",\"c = d + (d = 5)\",\"\",\"; no problemo\",\"f = (g = 6) + g\",\"end\"]}]}","code.102.potential-var-use-before-def.exception.spec.ts":"{\"suiteName\":\"Use variable before it is defined\",\"fileName\":\"code.102.potential-var-use-before-def.exception.spec.ts\",\"tests\":[{\"name\":\"does not get triggered here\",\"code\":[\"pro IDLitVisAxis2::OnViewportChange, oDestination\",\" compile_opt idl2, hidden\",\"\",\" if (obj_valid(oDestination)) then $\",\" oDestination.GetProperty, current_zoom = zoomFactor $\",\" else $\",\" zoomFactor = 1.0\",\"\",\"end\"]}]}","code.103.ambiguous-keyword-abbreviation.spec.ts":"{\"suiteName\":\"Keywords that are abbreviated but\",\"fileName\":\"code.103.ambiguous-keyword-abbreviation.spec.ts\",\"tests\":[{\"name\":\"have multiple for auto complete\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw1: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\"; kw2: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myclass::mymethod, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw1: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\"; kw2: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro myclass::mymethod, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2\",\"\",\"end\",\"\",\";+\",\"; :myclass:\",\";-\",\"pro myclass__define\",\" compile_opt idl2\",\"\",\" !null = {myclass}\",\"\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw1: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\"; kw2: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function auto_doc_example, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw1: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\"; kw2: bidirectional, optional, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro auto_doc_example, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main leve program\",\"compile_opt idl2\",\"\",\"; problem 1\",\"auto_doc_example, /kw\",\"\",\"; problem 2\",\"!null = auto_doc_example(kw = 5)\",\"\",\"a = {myclass}\",\"\",\"; problem 3\",\"a.mymethod, kw = 5\",\"\",\"; problem 4\",\"!null = a.mymethod(/kw)\",\"\",\"end\"]}]}","code.103.ambiguous-keyword-abbreviation.exceptions.spec.ts":"{\"suiteName\":\"Keywords that could be abbreviated\",\"fileName\":\"code.103.ambiguous-keyword-abbreviation.exceptions.spec.ts\",\"tests\":[{\"name\":\"but have a direct match\",\"code\":[\"; main leve program\",\"compile_opt idl2\",\"\",\"; problem 1\",\"device, /close\",\"\",\"end\"]}]}","code.104.unused-var.spec.ts":"{\"suiteName\":\"Unused variable\",\"fileName\":\"code.104.unused-var.spec.ts\",\"tests\":[{\"name\":\"problems with args, kws, and vars\",\"code\":[\"function test1, a, b, kw = kw\",\" compile_opt idl2\",\" c = 5\",\" return, 1\",\"end\"]},{\"name\":\"no problems when used\",\"code\":[\"function test1, a, b, kw = kw\",\" compile_opt idl2\",\" c = 5\",\" !null = a + b + c + keyword_set(kw)\",\" return, 1\",\"end\"]}]}","code.104.unused-var.exceptions1.spec.ts":"{\"suiteName\":\"Unused variable\",\"fileName\":\"code.104.unused-var.exceptions1.spec.ts\",\"tests\":[{\"name\":\"exceptions for static references\",\"code\":[\"compile_opt idl2\",\"!null = ENVI.openRaster()\",\"end\"]}]}","code.104.unused-var.exceptions2.spec.ts":"{\"suiteName\":\"Unused var exceptions when parentheses for indexing\",\"fileName\":\"code.104.unused-var.exceptions2.spec.ts\",\"tests\":[{\"name\":\"is var\",\"code\":[\";+ my var\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"is not var\",\"code\":[\"compile_opt strictarr\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"is not var\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"is not var\",\"code\":[\"compile_opt idl3\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]}]}","code.105.illegal-var-index.spec.ts":"{\"suiteName\":\"Indexing with parentheses\",\"fileName\":\"code.105.illegal-var-index.spec.ts\",\"tests\":[{\"name\":\"for simple case\",\"code\":[\";+ my var\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt strictarr\",\"code\":[\"compile_opt strictarr\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl2\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl3\",\"code\":[\"compile_opt idl3\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]}]}","type-validation-reference.spec.ts":"{\"suiteName\":\"All the places we want to make sure we test for\",\"fileName\":\"type-validation-reference.spec.ts\",\"tests\":[{\"name\":\"type validation\",\"code\":[\";+\",\"; :Arguments:\",\"; arg3: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro validate_problems, arg3, arg4\",\" compile_opt idl3\",\"\",\" ; validation edge cases\",\" ; same variables should always have validation applied, but not always saved\",\" dup1 = arg3[arg4]\",\" dup1 = arg3[arg4]\",\"\",\" ; anything with assignment before should validate\",\" !x.charsize = arg3[arg4]\",\" !null = arg3[arg4]\",\"\",\" ; arguments and keywords\",\" a = polot1(arg3[arg4], $\",\" arg3[arg4], $\",\" thing = arg3[arg4], $\",\" thang = arg3[arg4])\",\"\",\" ; left-side of the equation\",\" arg3[arg4] = 5\",\" (arg3[arg4]) = 5\",\" (myfunc(arg3[arg4])) = 5\",\" !null = (myfunc2(arg3[arg4]))\",\" !null = (myfunc3(arg3[arg4])) + 1\",\"\",\" ; arguments\",\" a = polot2(arg3[arg4], arg3[arg4])\",\"end\"]}]}"},"auto-selected-token-tests":{"basic.spec.ts":"{\"suiteName\":\"Correctly identifies search terms from syntax tree\",\"fileName\":\"basic.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"code\":[\"function myfunc\",\" return,1\",\"end\",\"\",\"; main level\",\"something = 42\",\"end\"],\"position\":[{\"line\":0,\"character\":0},{\"line\":3,\"character\":0}]}]}","keywords.spec.ts":"{\"suiteName\":\"Correctly identifies keywords from routine calls\",\"fileName\":\"keywords.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"code\":[\"; main level\",\"r = ENVIRaster(NCOLUMNS = nCols, NROWS = nrows)\",\"end\"],\"position\":[{\"line\":1,\"character\":20},{\"line\":1,\"character\":35}]}]}","proper-parent.spec.ts":"{\"suiteName\":\"Correctly identifies search terms from syntax tree\",\"fileName\":\"proper-parent.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens with multiple parent routines\",\"code\":[\"function myfunc2\",\" compile_opt idl2\",\" a = 42\",\" return,1\",\"end\",\"\",\"function myfunc1\",\" compile_opt idl2\",\" a = 17\",\" return,1\",\"end\"],\"position\":[{\"line\":2,\"character\":2},{\"line\":8,\"character\":2}]}]}","relaxed.spec.ts":"{\"suiteName\":\"Correctly use relaxed options for hover help\",\"fileName\":\"relaxed.spec.ts\",\"tests\":[{\"name\":\"at end of assignment\",\"code\":[\"function myfunc1\",\" compile_opt idl2\",\" a = \",\" return,1\",\"end\"],\"position\":[{\"line\":2,\"character\":5},{\"line\":8,\"character\":6}]}]}","within-parent.spec.ts":"{\"suiteName\":\"Find the right token when we do/don't have anything selected\",\"fileName\":\"within-parent.spec.ts\",\"tests\":[{\"name\":\"with a branch token\",\"code\":[\"args.setData, \",\"end\"],\"position\":[{\"line\":0,\"character\":12},{\"line\":0,\"character\":13},{\"line\":0,\"character\":14},{\"line\":0,\"character\":15},{\"line\":0,\"character\":16}]}]}"},"auto-hover-help-tests":{"bracket-paren.1.spec.ts":"{\"suiteName\":\"Correctly provides hover help for\",\"fileName\":\"bracket-paren.1.spec.ts\",\"tests\":[{\"name\":\"things after brackets and parentheses\",\"file\":\"idl/test/hover-help/bracket_paren.pro\",\"position\":[{\"line\":14,\"character\":20},{\"line\":17,\"character\":21},{\"line\":17,\"character\":27},{\"line\":20,\"character\":20},{\"line\":23,\"character\":25},{\"line\":24,\"character\":13}]}]}","comment-regression.spec.ts":"{\"suiteName\":\"Correctly get hover help\",\"fileName\":\"comment-regression.spec.ts\",\"tests\":[{\"name\":\"for comment edge case\",\"file\":\"idl/test/hover-help/comment_regression.pro\",\"position\":[{\"line\":3,\"character\":12},{\"line\":5,\"character\":13}]}]}","docs-overrides.spec.ts":"{\"suiteName\":\"Correctly overrides doc hover help\",\"fileName\":\"docs-overrides.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/docs_overrides.pro\",\"position\":[{\"line\":3,\"character\":8},{\"line\":3,\"character\":13},{\"line\":3,\"character\":22}]}]}","docs-overrides.2.spec.ts":"{\"suiteName\":\"Correctly overrides doc hover help\",\"fileName\":\"docs-overrides.2.spec.ts\",\"tests\":[{\"name\":\"for structure properties\",\"file\":\"idl/test/hover-help/docs_overrides2.pro\",\"position\":[{\"line\":6,\"character\":11}]}]}","ex-1.spec.ts":"{\"suiteName\":\"Correctly identifies search terms from syntax tree\",\"fileName\":\"ex-1.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/awesomerasterintersection.pro\",\"position\":[{\"line\":87,\"character\":10},{\"line\":90,\"character\":7},{\"line\":91,\"character\":25}]}]}","ex-2.spec.ts":"{\"suiteName\":\"Correctly identifies keywords from routine calls\",\"fileName\":\"ex-2.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/myfunc.pro\",\"position\":[{\"line\":24,\"character\":12},{\"line\":24,\"character\":20},{\"line\":27,\"character\":6},{\"line\":32,\"character\":6},{\"line\":40,\"character\":13}]}]}","ex-3.spec.ts":"{\"suiteName\":\"Correctly finds no information for parameters in docs but not code\",\"fileName\":\"ex-3.spec.ts\",\"tests\":[{\"name\":\"with keywords and arguments\",\"file\":\"idl/test/hover-help/only_code.pro\",\"position\":[{\"line\":26,\"character\":2},{\"line\":27,\"character\":2}]}]}","init-methods.spec.ts":"{\"suiteName\":\"Verify hover-help for\",\"fileName\":\"init-methods.spec.ts\",\"tests\":[{\"name\":\"init methods\",\"file\":\"idl/test/hover-help/init_method.pro\",\"position\":[{\"line\":13,\"character\":14},{\"line\":16,\"character\":19}]}]}","keywords.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"keywords.spec.ts\",\"tests\":[{\"name\":\"abbreviated keywords\",\"file\":\"idl/test/hover-help/keywords.pro\",\"position\":[{\"line\":4,\"character\":13}]}]}","literal-types.spec.ts":"{\"suiteName\":\"Correctly display help for literal types\",\"fileName\":\"literal-types.spec.ts\",\"tests\":[{\"name\":\"for numbers and strings\",\"file\":\"idl/test/hover-help/literal_types.pro\",\"position\":[{\"line\":1,\"character\":2},{\"line\":2,\"character\":2},{\"line\":3,\"character\":2},{\"line\":4,\"character\":2},{\"line\":5,\"character\":2}]}]}","no-end.spec.ts":"{\"suiteName\":\"Correctly does not provide hover help\",\"fileName\":\"no-end.spec.ts\",\"tests\":[{\"name\":\"for end tokens but does for the beginning\",\"file\":\"idl/test/hover-help/middle_functions.pro\",\"position\":[{\"line\":3,\"character\":6},{\"line\":3,\"character\":10}]}]}","obj-new.spec.ts":"{\"suiteName\":\"Correctly find find definition from obj new\",\"fileName\":\"obj-new.spec.ts\",\"tests\":[{\"name\":\"case 1\",\"file\":\"idl/test/hover-help/obj_new.pro\",\"position\":[{\"line\":53,\"character\":12}]},{\"name\":\"case 2\",\"file\":\"idl/test/hover-help/obj_new.pro\",\"position\":[{\"line\":56,\"character\":12}]},{\"name\":\"keywords\",\"file\":\"idl/test/hover-help/obj_new.pro\",\"position\":[{\"line\":56,\"character\":35}]}]}","structures.spec.ts":"{\"suiteName\":\"Provide hover help for\",\"fileName\":\"structures.spec.ts\",\"tests\":[{\"name\":\"anonymous structures\",\"file\":\"idl/test/hover-help/structures.pro\",\"position\":[{\"line\":8,\"character\":10},{\"line\":9,\"character\":12},{\"line\":10,\"character\":14},{\"line\":11,\"character\":12}]}]}","structures-properties.spec.ts":"{\"suiteName\":\"Provide hover help for\",\"fileName\":\"structures-properties.spec.ts\",\"tests\":[{\"name\":\"named structure properties\",\"file\":\"idl/test/hover-help/structures2.pro\",\"position\":[{\"line\":13,\"character\":24},{\"line\":13,\"character\":34}]},{\"name\":\"anonymous structure properties\",\"file\":\"idl/test/hover-help/structures2.pro\",\"position\":[{\"line\":15,\"character\":9},{\"line\":15,\"character\":25}]}]}","syntax-errors.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"syntax-errors.spec.ts\",\"tests\":[{\"name\":\"incorrect function call\",\"file\":\"idl/test/hover-help/syntax_error.pro\",\"position\":[{\"line\":1,\"character\":8}]},{\"name\":\"the end of the function call start (regression test for crash)\",\"file\":\"idl/test/hover-help/syntax_error.pro\",\"position\":[{\"line\":1,\"character\":11}]}]}","tasks.spec.ts":"{\"suiteName\":\"Task type hover help\",\"fileName\":\"tasks.spec.ts\",\"tests\":[{\"name\":\"as regression for task type parsing and serialization\",\"file\":\"idl/test/hover-help/tasks.pro\",\"position\":[{\"line\":13,\"character\":14},{\"line\":14,\"character\":14},{\"line\":15,\"character\":14}]}]}","variables.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"variables.spec.ts\",\"tests\":[{\"name\":\"system variables\",\"file\":\"idl/test/hover-help/variables.pro\",\"position\":[{\"line\":5,\"character\":2}]}]}","type-detection.methods.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"type-detection.methods.spec.ts\",\"tests\":[{\"name\":\"function method\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":10,\"character\":13}]},{\"name\":\"procedure methods\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":13,\"character\":6}]}]}","type-detection.properties.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"type-detection.properties.spec.ts\",\"tests\":[{\"name\":\"first level properties that exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":16,\"character\":16}]},{\"name\":\"secondary properties that exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":16,\"character\":23}]},{\"name\":\"first level properties that dont exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":19,\"character\":16}]},{\"name\":\"secondary properties that dont exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":22,\"character\":25}]},{\"name\":\"static properties that exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":25,\"character\":16}]},{\"name\":\"static properties that dont exist\",\"file\":\"idl/test/hover-help/types.pro\",\"position\":[{\"line\":28,\"character\":22}]}]}","type-detection.methods-inheritance.spec.ts":"{\"suiteName\":\"Correctly provide hover help for\",\"fileName\":\"type-detection.methods-inheritance.spec.ts\",\"tests\":[{\"name\":\"function method\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":10,\"character\":13}]},{\"name\":\"procedure methods\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":13,\"character\":6}]}]}","type-detection.properties-inheritance.spec.ts":"{\"suiteName\":\"Correctly provide hover help for inheritance of\",\"fileName\":\"type-detection.properties-inheritance.spec.ts\",\"tests\":[{\"name\":\"first level properties that exist\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":16,\"character\":16}]},{\"name\":\"secondary properties that exist\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":16,\"character\":23}]},{\"name\":\"first level properties that dont exist\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":19,\"character\":16}]},{\"name\":\"secondary properties that dont exist\",\"file\":\"idl/test/hover-help/types_inheritance.pro\",\"position\":[{\"line\":22,\"character\":25}]}]}","type-detection.sysvar.spec.ts":"{\"suiteName\":\"Correctly provide hover help for system variable\",\"fileName\":\"type-detection.sysvar.spec.ts\",\"tests\":[{\"name\":\"properties that exist\",\"file\":\"idl/test/hover-help/types_sysvar.pro\",\"position\":[{\"line\":3,\"character\":15}]},{\"name\":\"properties that don't exist\",\"file\":\"idl/test/hover-help/types_sysvar.pro\",\"position\":[{\"line\":4,\"character\":14}]}]}","type-detection.keywords.spec.ts":"{\"suiteName\":\"Correctly provide hover help for keywords\",\"fileName\":\"type-detection.keywords.spec.ts\",\"tests\":[{\"name\":\"in method calls\",\"file\":\"idl/test/hover-help/types_keywords.pro\",\"position\":[{\"line\":10,\"character\":27},{\"line\":12,\"character\":19},{\"line\":12,\"character\":27}]}]}"},"auto-token-definition-tests":{"functions.spec.ts":"{\"suiteName\":\"Correctly find function definitions\",\"fileName\":\"functions.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":11}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":61,\"character\":11}]}]}","function-methods.spec.ts":"{\"suiteName\":\"Correctly find definitions for function methods\",\"fileName\":\"function-methods.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":17},{\"line\":85,\"character\":14}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":88,\"character\":19}]}]}","include.spec.ts":"{\"suiteName\":\"Correctly find find include\",\"fileName\":\"include.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/include_test.pro\"],\"position\":[{\"line\":4,\"character\":7}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/include_test.pro\"],\"position\":[{\"line\":7,\"character\":8}]}]}","keywords.procedures.spec.ts":"{\"suiteName\":\"Correctly find definitions for keywords\",\"fileName\":\"keywords.procedures.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":7}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":16},{\"line\":55,\"character\":8}]},{\"name\":\"real binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":30}]},{\"name\":\"fake binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":37}]}]}","keywords.procedure-methods.spec.ts":"{\"suiteName\":\"Correctly find definitions for keywords\",\"fileName\":\"keywords.procedure-methods.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":16},{\"line\":76,\"character\":16}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":25},{\"line\":76,\"character\":25},{\"line\":79,\"character\":17}]},{\"name\":\"real binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":38},{\"line\":76,\"character\":38}]},{\"name\":\"fake binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":45},{\"line\":76,\"character\":45}]}]}","keywords.functions.spec.ts":"{\"suiteName\":\"Correctly find definitions for keywords\",\"fileName\":\"keywords.functions.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":15}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":24},{\"line\":61,\"character\":16}]},{\"name\":\"real binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":37}]},{\"name\":\"fake binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":58,\"character\":44}]}]}","keywords.function-methods.spec.ts":"{\"suiteName\":\"Correctly find definitions for keywords\",\"fileName\":\"keywords.function-methods.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":24},{\"line\":85,\"character\":24}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":33},{\"line\":85,\"character\":33},{\"line\":88,\"character\":25}]},{\"name\":\"real binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":46},{\"line\":85,\"character\":46}]},{\"name\":\"fake binary\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":82,\"character\":53},{\"line\":85,\"character\":53}]}]}","obj-new.spec.ts":"{\"suiteName\":\"Correctly find find definition from obj new\",\"fileName\":\"obj-new.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/obj_new.pro\"],\"position\":[{\"line\":53,\"character\":12}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/obj_new.pro\"],\"position\":[{\"line\":56,\"character\":12}]}]}","procedures.spec.ts":"{\"suiteName\":\"Correctly find procedure definitions\",\"fileName\":\"procedures.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":52,\"character\":6}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":55,\"character\":2}]}]}","procedure-methods.spec.ts":"{\"suiteName\":\"Correctly find definitions for procedure methods\",\"fileName\":\"procedure-methods.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":73,\"character\":8},{\"line\":76,\"character\":8}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":79,\"character\":6}]}]}","properties.spec.ts":"{\"suiteName\":\"Correctly find definitions for properties\",\"fileName\":\"properties.spec.ts\",\"tests\":[{\"name\":\"real\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":64,\"character\":14},{\"line\":67,\"character\":14}]},{\"name\":\"fake\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":70,\"character\":14}]}]}","structures.spec.ts":"{\"suiteName\":\"Correctly find definitions in structures\",\"fileName\":\"structures.spec.ts\",\"tests\":[{\"name\":\"using structure names\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":40,\"character\":9}]},{\"name\":\"using properties (inherited, ours, fake)\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":43,\"character\":19},{\"line\":43,\"character\":31},{\"line\":43,\"character\":42}]},{\"name\":\"anonymous properties\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":94,\"character\":22}]}]}","tasks.spec.ts":"{\"suiteName\":\"Correctly find definitions for task files\",\"fileName\":\"tasks.spec.ts\",\"tests\":[{\"name\":\"from ENVITask function\",\"files\":[\"idl/test/token-def/tasks.pro\",\"idl/test/token-def/atanomalydetection.task\"],\"position\":[{\"line\":2,\"character\":12}]}]}","variables.spec.ts":"{\"suiteName\":\"Correctly find definitions in structures\",\"fileName\":\"variables.spec.ts\",\"tests\":[{\"name\":\"real variables\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":46,\"character\":9}]},{\"name\":\"fake variables\",\"files\":[\"idl/test/token-def/all_cases.pro\"],\"position\":[{\"line\":49,\"character\":9}]}]}"},"auto-auto-complete-tests":{"bracket-paren.1.spec.ts":"{\"suiteName\":\"Correctly provides auto complete for\",\"fileName\":\"bracket-paren.1.spec.ts\",\"tests\":[{\"name\":\"things after brackets and parentheses\",\"file\":\"idl/test/auto-complete/bracket_paren.pro\",\"position\":[{\"line\":14,\"character\":18},{\"line\":17,\"character\":24},{\"line\":20,\"character\":17},{\"line\":23,\"character\":19},{\"line\":24,\"character\":11}]}]}","dont-complete.spec.ts":"{\"suiteName\":\"Don't do auto-complete\",\"fileName\":\"dont-complete.spec.ts\",\"tests\":[{\"name\":\"for any of these\",\"file\":\"idl/test/auto-complete/dont_complete.pro\",\"position\":[{\"line\":1,\"character\":18},{\"line\":1,\"character\":19},{\"line\":1,\"character\":34},{\"line\":6,\"character\":9},{\"line\":6,\"character\":10},{\"line\":6,\"character\":25},{\"line\":13,\"character\":13},{\"line\":16,\"character\":2},{\"line\":17,\"character\":2},{\"line\":20,\"character\":9},{\"line\":21,\"character\":9},{\"line\":22,\"character\":9},{\"line\":25,\"character\":10},{\"line\":28,\"character\":10}]}]}","executive-commands.1.spec.ts":"{\"suiteName\":\"Correctly send only executive commands\",\"fileName\":\"executive-commands.1.spec.ts\",\"tests\":[{\"name\":\"when we auto-complete\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":36,\"character\":2}]}]}","include-properties.spec.ts":"{\"suiteName\":\"Include properties\",\"fileName\":\"include-properties.spec.ts\",\"tests\":[{\"name\":\"for procedure methods with only dots\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":22,\"character\":4}]},{\"name\":\"for static properties\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":26,\"character\":15}]}]}","in-structures.1.spec.ts":"{\"suiteName\":\"Verify auto-complete in structures\",\"fileName\":\"in-structures.1.spec.ts\",\"tests\":[{\"name\":\"for properties, property completion, and normal property completion\",\"file\":\"idl/test/auto-complete/in_structures.pro\",\"position\":[{\"line\":17,\"character\":15},{\"line\":19,\"character\":22},{\"line\":21,\"character\":47}]}]}","include.spec.ts":"{\"suiteName\":\"Verify auto-complete for\",\"fileName\":\"include.spec.ts\",\"tests\":[{\"name\":\"include statements\",\"file\":\"idl/test/auto-complete/include.pro\",\"position\":[{\"line\":2,\"character\":1}]}]}","init-methods.spec.ts":"{\"suiteName\":\"Verify auto-complete for\",\"fileName\":\"init-methods.spec.ts\",\"tests\":[{\"name\":\"init methods\",\"file\":\"idl/test/auto-complete/init_method.pro\",\"position\":[{\"line\":13,\"character\":10},{\"line\":16,\"character\":18}]}]}","keywords.1.spec.ts":"{\"suiteName\":\"Correctly provides auto complete for keywords\",\"fileName\":\"keywords.1.spec.ts\",\"tests\":[{\"name\":\"things after brackets and parentheses\",\"file\":\"idl/test/auto-complete/keywords.pro\",\"position\":[{\"line\":4,\"character\":10},{\"line\":7,\"character\":11},{\"line\":10,\"character\":15},{\"line\":13,\"character\":13},{\"line\":16,\"character\":14}]}]}","keywords.2.spec.ts":"{\"suiteName\":\"Correctly exclude keywords\",\"fileName\":\"keywords.2.spec.ts\",\"tests\":[{\"name\":\"for these cases\",\"file\":\"idl/test/auto-complete/keywords.pro\",\"position\":[{\"line\":22,\"character\":12},{\"line\":23,\"character\":11},{\"line\":24,\"character\":9}]}]}","methods.1.spec.ts":"{\"suiteName\":\"Verify types being used for\",\"fileName\":\"methods.1.spec.ts\",\"tests\":[{\"name\":\"methods\",\"file\":\"idl/test/auto-complete/types.pro\",\"position\":[{\"line\":10,\"character\":8},{\"line\":13,\"character\":4},{\"line\":26,\"character\":12}]}]}","no-init.spec.ts":"{\"suiteName\":\"Exclude init method\",\"fileName\":\"no-init.spec.ts\",\"tests\":[{\"name\":\"for function methods\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":7,\"character\":12}]}]}","no-paren.spec.ts":"{\"suiteName\":\"Exclude parentheses\",\"fileName\":\"no-paren.spec.ts\",\"tests\":[{\"name\":\"for functions and function methods\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":10,\"character\":9},{\"line\":11,\"character\":12},{\"line\":12,\"character\":14}]}]}","no-properties.spec.ts":"{\"suiteName\":\"Exclude properties\",\"fileName\":\"no-properties.spec.ts\",\"tests\":[{\"name\":\"for function methods\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":18,\"character\":12},{\"line\":19,\"character\":14}]},{\"name\":\"for procedure method\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":23,\"character\":7}]}]}","no-variables.spec.ts":"{\"suiteName\":\"Exclude variables\",\"fileName\":\"no-variables.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":15,\"character\":9}]}]}","procedures.1.spec.ts":"{\"suiteName\":\"When in procedure, send procedure tokens\",\"fileName\":\"procedures.1.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"file\":\"idl/test/auto-complete/procedures.pro\",\"position\":[{\"line\":4,\"character\":2}]}]}","obj-new.spec.ts":"{\"suiteName\":\"Correctly return auto-complete from obj-new\",\"fileName\":\"obj-new.spec.ts\",\"tests\":[{\"name\":\"real\",\"file\":\"idl/test/auto-complete/obj_new.pro\",\"position\":[{\"line\":53,\"character\":26}]},{\"name\":\"fake\",\"file\":\"idl/test/auto-complete/obj_new.pro\",\"position\":[{\"line\":56,\"character\":29}]}]}","procedures.spec.ts":"{\"suiteName\":\"Procedures\",\"fileName\":\"procedures.spec.ts\",\"tests\":[{\"name\":\"including user and variables\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":2,\"character\":0}]}]}","properties.1.spec.ts":"{\"suiteName\":\"Verify types being used for\",\"fileName\":\"properties.1.spec.ts\",\"tests\":[{\"name\":\"properties\",\"file\":\"idl/test/auto-complete/types.pro\",\"position\":[{\"line\":16,\"character\":15},{\"line\":19,\"character\":21},{\"line\":19,\"character\":21}]}]}","regression.1.spec.ts":"{\"suiteName\":\"Regression tests\",\"fileName\":\"regression.1.spec.ts\",\"tests\":[{\"name\":\"for problems\",\"file\":\"idl/test/auto-complete/regression1.pro\",\"position\":[{\"line\":2,\"character\":28}]}]}","structures-anonymous.spec.ts":"{\"suiteName\":\"Structures\",\"fileName\":\"structures-anonymous.spec.ts\",\"tests\":[{\"name\":\"without a name\",\"file\":\"idl/test/auto-complete/structures.pro\",\"position\":[{\"line\":8,\"character\":12},{\"line\":9,\"character\":14},{\"line\":10,\"character\":21}]},{\"name\":\"auto-complete for structure names\",\"file\":\"idl/test/auto-complete/structures.pro\",\"position\":[{\"line\":13,\"character\":11},{\"line\":14,\"character\":14}]}]}","tasks.functions.spec.ts":"{\"suiteName\":\"Task auto complete\",\"fileName\":\"tasks.functions.spec.ts\",\"tests\":[{\"name\":\"to make sure they look nice\",\"file\":\"idl/test/auto-complete/task_functions.pro\",\"position\":[{\"line\":3,\"character\":8}],\"startsWith\":\"ENVITask\"}]}","tasks.properties.spec.ts":"{\"suiteName\":\"Task auto complete\",\"fileName\":\"tasks.properties.spec.ts\",\"tests\":[{\"name\":\"as regression for task type parsing\",\"file\":\"idl/test/auto-complete/tasks.pro\",\"position\":[{\"line\":13,\"character\":4},{\"line\":14,\"character\":4},{\"line\":15,\"character\":4}]}]}","method-regression.spec.ts":"{\"suiteName\":\"Methods\",\"fileName\":\"method-regression.spec.ts\",\"tests\":[{\"name\":\"inside the paren showing variables\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":10,\"character\":10},{\"line\":11,\"character\":13},{\"line\":12,\"character\":15}]}]}","system-variables.1.spec.ts":"{\"suiteName\":\"Correctly send only system variables\",\"fileName\":\"system-variables.1.spec.ts\",\"tests\":[{\"name\":\"when we auto-complete\",\"file\":\"idl/test/auto-complete/examples.pro\",\"position\":[{\"line\":29,\"character\":3},{\"line\":30,\"character\":9}]}]}","variables.1.spec.ts":"{\"suiteName\":\"Correctly finds the right variables\",\"fileName\":\"variables.1.spec.ts\",\"tests\":[{\"name\":\"when we auto-complete\",\"file\":\"idl/test/auto-complete/variables.pro\",\"position\":[{\"line\":6,\"character\":10},{\"line\":9,\"character\":2}]}]}"},"auto-local-global-scope-compile-types-tests":{"all-docs-work-right.spec.ts":"{\"suiteName\":\"Correctly gets docs and variables\",\"fileName\":\"all-docs-work-right.spec.ts\",\"tests\":[{\"name\":\"for a routine\",\"code\":[\"\",\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, KW1=kw1\",\" compile_opt idl2\",\" ;+ awesome variable with docs\",\" a = 42\",\" ;+\",\" ; Big comment block here\",\" ; like a great code writer\",\" ;-\",\" b = 42\",\"end\",\"\"]}]}","common.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"common.spec.ts\",\"tests\":[{\"name\":\"common, excluding the first of the common block\",\"code\":[\"pro color_edit_back\",\"compile_opt idl2\",\"\",\"common color_edit, wxsize, wysize, r0\",\"end\"]}]}","complex-docs-example1.spec.ts":"{\"suiteName\":\"Complex real world test\",\"fileName\":\"complex-docs-example1.spec.ts\",\"tests\":[{\"name\":\"with past failure in complex docs\",\"code\":[\";h+\",\"; Copyright (c) 2018 Harris Geospatial Solutions, Inc.\",\"; \",\"; Licensed under MIT. See LICENSE.txt for additional details and information.\",\";h-\",\"\",\"\",\"\",\";+\",\"; :Description:\",\"; Tool for determining the intersection between two rasters based on their\",\"; spatial reference and spatial extent. Both rasters will also contain only\",\"; the valid pixels from each scene for analysis. In other words, if a pixel\",\"; is `off` in the first image and not the second, it will be turned `off` in\",\"; each of the output rasters for consistency. If one of the rasters does not\",\"; have a data ignore value, then a pixel state mask is automatically generated\",\"; so that you can mask the output rasters if needed.\",\"; \",\"; The pixel size of the output rasters will be the smallest x and y\",\"; pixel size from each raster.\",\";\",\";\",\";\",\"; :Examples:\",\"; ```idl\",\"; ;start ENVI\",\"; e = envi(/HEADLESS)\",\"; \",\"; ;make sure we have access to our ENVI tasks\",\"; awesomeENVIAlgorithms, /INIT\",\"; \",\"; ;specify two rasters to process\",\"; raster1 = e.openRaster(file1)\",\"; raster2 = e.openRaster(file2)\",\"; \",\"; ;get our task\",\"; task = ENVITask('AwesomeRasterIntersection')\",\"; task.INPUT_RASTER1 = raster1\",\"; task.INPUT_RASTER2 = raster2\",\"; task.execute\",\"; \",\"; ;print our output locations\",\"; print, task.OUTPUT_RASTER1_URI\",\"; print, task.OUTPUT_RASTER2_URI\",\"; ```\",\";\",\"; :Keywords:\",\"; DEBUG: in, optional, type=boolean, private\",\"; If set, errors are stopped on.\",\"; DATA_IGNORE_VALUE: in, optional, type=number\",\"; If one or both of your input rasters do not have\",\"; a data ignore value metadata item, you can specify\",\"; GENERATE_PIXEL_STATE_MASK: in, optional, type=boolean\",\"; If set, then an addititonal output raster is created\",\"; that represents which pixels can be processed or not.\",\"; \",\"; This will automatically be generated if one of the input\",\"; images does not have a data ignore value.\",\"; INPUT_RASTER1: in, required, type=ENVIRaster\",\"; Specify the first raster to use for intersection.\",\"; INPUT_RASTER2: in, required, type=ENVIRaster\",\"; Specify the second raster to use for intersection\",\"; OUTPUT_GRID_DEFINITION: out, optional, type=ENVIGridDefinition\",\"; Optionally return the ENVIGridDefinition object used to get the intersection\",\"; of the two scenes.\",\"; OUTPUT_RASTER1_URI: in, optional, type=string\",\"; Optionally specify the fully-qualified filepath\",\"; for the location of the first intersect raster.\",\"; OUTPUT_RASTER2_URI: in, optional, type=string\",\"; Optionally specify the fully-qualified filepath\",\"; for the location of the second intersect raster.\",\"; OUTPUT_MASK_RASTER_URI: in, optional, type=string\",\"; Optionally specify the fully-qualified filepath\",\"; for the location of the pixel state mask. Only applies\",\"; when `GENERATE_PIXEL_STATE_MASK` is set or one of the \",\"; input rasters does not have a data ignore value.\",\"; RESAMPLING: in, optional, type=string\",\"; Optionally return the ENVIGridDefinition object used to get the intersection\",\"; of the two scenes. Specify one of the following options:\",\"; - Nearest Neighbor\",\"; - Bilinear\",\"; - Cubic Convolution\",\";\",\"; :Tooltip:\",\"; Calculates the intersection of two rasters such that both\",\"; have the same spatial extent and spatial dimensions\",\";\",\"; :Author: Zachary Norman - GitHub: [znorman-harris](https://github.com/znorman-harris)\",\";-\",\"pro awesomeRasterIntersection, $\",\" DEBUG = debug,$\",\" DATA_IGNORE_VALUE = data_ignore_value,$\",\" GENERATE_PIXEL_STATE_MASK = generate_pixel_state_mask,$\",\" INPUT_RASTER1 = input_raster1,$\",\" INPUT_RASTER2 = input_raster2,$\",\" OUTPUT_MASK_RASTER_URI = output_mask_raster_uri,$\",\" OUTPUT_GRID_DEFINITION = output_grid_definition,$\",\" OUTPUT_RASTER1_URI = output_raster1_uri,$\",\" OUTPUT_RASTER2_URI = output_raster2_uri,$\",\" RESAMPLING = resampling\",\" compile_opt idl2, hidden\",\"end\",\"\"]}]}","complex-docs-example2.spec.ts":"{\"suiteName\":\"Complex real world test\",\"fileName\":\"complex-docs-example2.spec.ts\",\"tests\":[{\"name\":\"with past failure in complex docs\",\"code\":[\";+\",\"; :Description:\",\"; Function which will initialize the bdige_it object and start all bridges. When bridges are initialized\",\"; they are done so in parallel, but whe function will not return until every bridge is idle again.\",\";\",\"; :Params:\",\"; nbridges: in, required, type=int\",\"; The number of bridges that you want to create\",\";\",\"; :Keywords:\",\"; INIT : in, optional, type=strarr\",\"; Optional argument which allows you to pass in a string array of extra commands\",\"; to have each IDL_IDLBridge object execute upon creation.\",\"; MSG : in, optional, type=string\",\"; Optional argument to show the message prefix when a bridge process has completed for the TIME\",\"; keyword in bridge_it::run and bridge_it::run().\",\"; LOGDIR : in, optional, type=string\",\"; Specify the directory that the log file will be written to. The log file is just a text file with\",\"; all of the IDL Console output from each child process.\",\"; NREFRESH : in, optional, type=long\",\"; Specify the number of bridge processes to execute before closing and re-starting the\",\"; child process. Necessary for some ENVI routines so that we don't have memory fragmentation\",\"; regarding opening lots of small rasters.\",\"; PREFIX : in, optional, type=string, default='_KW_'\",\"; This optional keyword specifies the prefix which is used to differentiate between arguments and\",\"; keywords when it comes time to parse the arguments and keyword that will be passed into a routine.\",\";\",\"; :Author: Zachary Norman - GitHub: [znorman-harris](https://github.com/znorman-harris)\",\";\",\";-\",\"function bridge_it::Init, nbridges, INIT = init, MSG = msg, LOGDIR = logdir, NREFRESH = nrefresh, PREFIX = prefix\",\" compile_opt idl2, hidden\",\" on_error, 2\",\"\",\" return, 1\",\"end\"]}]}","document-vars.spec.ts":"{\"suiteName\":\"Correctly extract docs for\",\"fileName\":\"document-vars.spec.ts\",\"tests\":[{\"name\":\"variables with single-line block\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+ meaning of life\",\" a = 42\",\"end\"]},{\"name\":\"variables with multi-line block\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+\",\" ; Some things are really awesome\",\" ; and need a big description\",\" ;-\",\" a = 42\",\"end\"]},{\"name\":\"only use docs from first encounter\",\"code\":[\"pro myclass::mymethod, var1\",\" compile_opt idl2\",\" ;+\",\" ; Some things are really awesome\",\" ; and need a big description\",\" ;-\",\" a = 42\",\"\",\" ;+ second docs are ignored\",\" a = 42\",\"end\"]}]}","functions.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"functions.spec.ts\",\"tests\":[{\"name\":\"functions\",\"code\":[\"function myfunc, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\"]}]}","function-methods.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"function-methods.spec.ts\",\"tests\":[{\"name\":\"function methods\",\"code\":[\"function myclass::mymethod, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\"]}]}","function-methods.init.spec.ts":"{\"suiteName\":\"Add function for\",\"fileName\":\"function-methods.init.spec.ts\",\"tests\":[{\"name\":\"class init methods\",\"code\":[\"function MyClass::init, a, b, c, kw2 = kw2\",\" compile_opt idl2\",\"\",\" ; set data type correctly for local variable\",\" z = MyClass()\",\"\",\" return, 1\",\"end\"]}]}","inherit-args-docs.spec.ts":"{\"suiteName\":\"Correctly inherits docs for\",\"fileName\":\"inherit-args-docs.spec.ts\",\"tests\":[{\"name\":\"arguments\",\"code\":[\"\",\";+\",\"; My procedure\",\";\",\"; :Args:\",\"; var1: in, required, any\",\"; My favorite thing\",\";\",\";-\",\"pro mypro, var1\",\" compile_opt idl2\",\"end\",\"\"]}]}","inherit-kw-docs.spec.ts":"{\"suiteName\":\"Correctly inherits docs for\",\"fileName\":\"inherit-kw-docs.spec.ts\",\"tests\":[{\"name\":\"keywords\",\"code\":[\"\",\";+\",\"; My procedure\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, KW1=kw1\",\" compile_opt idl2\",\"end\",\"\"]}]}","inherit-private-docs.spec.ts":"{\"suiteName\":\"Correctly inherits docs for\",\"fileName\":\"inherit-private-docs.spec.ts\",\"tests\":[{\"name\":\"private\",\"code\":[\"\",\";+\",\"; My procedure\",\";\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean, private\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, KW1=kw1\",\" compile_opt idl2\",\"end\",\"\"]}]}","lambda.no-vars.spec.ts":"{\"suiteName\":\"With lambda functions\",\"fileName\":\"lambda.no-vars.spec.ts\",\"tests\":[{\"name\":\"do not extract variables\",\"code\":[\"; main level\",\"compile_opt idl2\",\"!null = lambda(n:n le 3 || min(n mod [2:fix(sqrt(n))]))\",\"end\"]}]}","main.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"main.spec.ts\",\"tests\":[{\"name\":\"main level\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"mypro, a, b, c, d\",\"end\"]}]}","notebook-parse.compile-opt.1.spec.ts":"{\"suiteName\":\"Verify notebook parsing\",\"fileName\":\"notebook-parse.compile-opt.1.spec.ts\",\"tests\":[{\"name\":\"adds compile-opt idl2 for main and gets right default type\",\"code\":[\"a = 42\",\"\",\"end\"],\"config\":{\"isNotebook\":true}}]}","notebook-parse.compile-opt.exceptions.spec.ts":"{\"suiteName\":\"Verify notebook parsing\",\"fileName\":\"notebook-parse.compile-opt.exceptions.spec.ts\",\"tests\":[{\"name\":\"ignores compile opt idl2 for procedures\",\"code\":[\"pro myPro\",\" print, 'Hello world'\",\"end\"],\"config\":{\"isNotebook\":true}},{\"name\":\"ignores compile opt idl2 for functions\",\"code\":[\"function myPro\",\" print, 'Hello world'\",\" return 42\",\"end\"],\"config\":{\"isNotebook\":true}}]}","only-from-code.spec.ts":"{\"suiteName\":\"Only use code for docs\",\"fileName\":\"only-from-code.spec.ts\",\"tests\":[{\"name\":\"and exclude incorrectly documented parameters\",\"code\":[\";+\",\"; Header\",\";\",\"; :Args:\",\"; a: in, required, int\",\"; Some cool statement across\",\";\",\"; multiple lines\",\"; b: in, required, string\",\"; Some cool statement across\",\";\",\"; multiple lines\",\"; :Keywords:\",\"; kw1: in, required, int\",\"; Some cool statement across\",\";\",\"; multiple lines\",\"; kw2: in, required, string\",\"; Some cool statement across\",\";\",\"; multiple lines\",\";\",\"; :Author: Meeeeeeeeeeeeeeeeeee\",\"\",\"\",\"\",\"\",\"pro myPro, a, kw1 = kw1\",\"\",\"\",\" print, 'Hello world'\",\"\",\"\",\"end\"]}]}","parse-fast.ignore-docs.1.spec.ts":"{\"suiteName\":\"Verify fast parsing ignores docs\",\"fileName\":\"parse-fast.ignore-docs.1.spec.ts\",\"tests\":[{\"name\":\"for structures\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: Long\",\"; Placeholder docs for argument or keyword\",\"; prop2: ENVIRaster\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro mystruct__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"],\"config\":{\"full\":false}}]}","parse-fast.ignore-docs.2.spec.ts":"{\"suiteName\":\"Verify fast parsing ignores docs\",\"fileName\":\"parse-fast.ignore-docs.2.spec.ts\",\"tests\":[{\"name\":\"for procedures\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, envitask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idltask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, ENVITask | ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, IDLTask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, arg3, arg4, arg5, KW1 = kw1\",\" compile_opt idl3\",\"\",\"end\"],\"config\":{\"full\":false}}]}","parse-fast.ignore-docs.3.spec.ts":"{\"suiteName\":\"Verify fast parsing ignores docs\",\"fileName\":\"parse-fast.ignore-docs.3.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, envitask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idltask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, ENVITask | ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, IDLTask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myfunc, arg1, arg2, arg3, arg4, arg5, KW1 = kw1\",\" compile_opt idl3\",\" return, 42\",\"end\"],\"config\":{\"full\":false}}]}","populate-structures.1.spec.ts":"{\"suiteName\":\"Correctly populate structures\",\"fileName\":\"populate-structures.1.spec.ts\",\"tests\":[{\"name\":\"in class definitions\",\"code\":[\"pro mystruct__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"end\"]},{\"name\":\"with no properties\",\"code\":[\"pro mystruct__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct}\",\"end\"]}]}","populate-structures.2.spec.ts":"{\"suiteName\":\"Use docs for property types\",\"fileName\":\"populate-structures.2.spec.ts\",\"tests\":[{\"name\":\"in structures\",\"code\":[\";+\",\"; :MyStruct:\",\"; prop: Long\",\"; Placeholder docs for argument or keyword\",\"; prop2: ENVIRaster\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro mystruct__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"]}]}","populate-structures.3.spec.ts":"{\"suiteName\":\"Find them in\",\"fileName\":\"populate-structures.3.spec.ts\",\"tests\":[{\"name\":\"normal procedures\",\"code\":[\"pro define_these_structures\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"end\"]}]}","populate-structures.4.spec.ts":"{\"suiteName\":\"Find them in\",\"fileName\":\"populate-structures.4.spec.ts\",\"tests\":[{\"name\":\"normal functions\",\"code\":[\"function define_these_structures\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"return, 1\",\"end\"]}]}","populate-structures.5.spec.ts":"{\"suiteName\":\"Find them in\",\"fileName\":\"populate-structures.5.spec.ts\",\"tests\":[{\"name\":\"procedure methods\",\"code\":[\"pro define_these_structures::method\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"end\"]}]}","populate-structures.6.spec.ts":"{\"suiteName\":\"Find them in\",\"fileName\":\"populate-structures.6.spec.ts\",\"tests\":[{\"name\":\"function methods\",\"code\":[\"function define_these_structures::method\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"return, 1\",\"end\"]}]}","populate-structures.7.spec.ts":"{\"suiteName\":\"Ignore them in\",\"fileName\":\"populate-structures.7.spec.ts\",\"tests\":[{\"name\":\"procedures\",\"code\":[\"pro my_def__define\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"if ~_exists then defsysv, '!notebook_magic', {IDLNotebookMagic}\",\"\",\"end\"]},{\"name\":\"as nested properties\",\"code\":[\"pro my_def__define\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"!null = {OtherStruct, prop:{SecondOtherStruct}}\",\"\",\"end\"]}]}","populate-structures.8.spec.ts":"{\"suiteName\":\"Take first instance we encounter\",\"fileName\":\"populate-structures.8.spec.ts\",\"tests\":[{\"name\":\"with non-full parse\",\"code\":[\"pro my_def__define\",\"compile_opt idl2\",\"fhdr = {WAVFILEHEADER, $\",\" friff: bytarr(4), $ ; A four char string\",\" fsize: 0ul, $\",\" fwave: bytarr(4) $ ; A four char string\",\"}\",\"\",\"if ~_exists then defsysv, '!notebook_magic', {WAVFILEHEADER}\",\"\",\"end\"],\"config\":{\"full\":false}}]}","procedures.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"procedures.spec.ts\",\"tests\":[{\"name\":\"procedures\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]}]}","procedure-methods.spec.ts":"{\"suiteName\":\"Correctly extract variables from\",\"fileName\":\"procedure-methods.spec.ts\",\"tests\":[{\"name\":\"procedure methods\",\"code\":[\"pro myclass::mymethod, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\" KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]}]}","tasks.from-docs.spec.ts":"{\"suiteName\":\"Verify type parsing for\",\"fileName\":\"tasks.from-docs.spec.ts\",\"tests\":[{\"name\":\"ENVI and IDL Tasks in docs\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, envitask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idltask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, ENVITask | ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, IDLTask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, arg3, arg4, arg5\",\" compile_opt idl3\",\"\",\"end\"]}]}","tasks.guessing-from-code.spec.ts":"{\"suiteName\":\"Verify behaviors for task types\",\"fileName\":\"tasks.guessing-from-code.spec.ts\",\"tests\":[{\"name\":\"where we determine types from code\",\"code\":[\"compile_opt idl2\",\"\",\"mosaic1 = ENVITask('BuildMosaicRaster')\",\"mosaic2 = ENVITask(routine_dir() + 'buildmosaicraster.task')\",\"\",\"uri = 'buildmosaicraster.task'\",\"mosaic3 = ENVITask(uri)\",\"\",\"envitaskany1 = ENVITask(uri + uri)\",\"\",\"idlmosaic1 = IDLTask('BuildMosaicRaster')\",\"idlmosaic2 = IDLTask(routine_dir() + 'buildmosaicraster.task')\",\"\",\"idlmosaic3 = IDLTask(uri)\",\"\",\"idltaskany1 = IDLTask(uri + uri)\",\"end\"]}]}","types.from-args.spec.ts":"{\"suiteName\":\"Types from output arguments\",\"fileName\":\"types.from-args.spec.ts\",\"tests\":[{\"name\":\"and exclude incorrectly documented parameters\",\"code\":[\";+\",\"; :Arguments:\",\"; a: in, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\"; b: out, required, Long\",\"; Placeholder docs for argument, keyword, or property\",\"; c: out, required, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro auto_doc_example, a, b, c\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"auto_doc_example, arg1, arg2, arg3\",\"end\"]}]}","types.from-assignment-weird.spec.ts":"{\"suiteName\":\"Types from assignment\",\"fileName\":\"types.from-assignment-weird.spec.ts\",\"tests\":[{\"name\":\"where we define vars in-line\",\"code\":[\"; main level\",\"compile_opt idl2\",\"\",\"; any because using var before defined\",\"c = d + (d = 5)\",\"\",\"; number\",\"f = (g = 6) + g\",\"end\"]}]}","types.arrays.brackets.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.arrays.brackets.spec.ts\",\"tests\":[{\"name\":\"array creation using brackets\",\"code\":[\"pro array_creation\",\" compile_opt idl2\",\"\",\" ; long\",\" a = [1, 2, 3, 4]\",\"\",\" ; float\",\" b = [1, 2, 3, 4.]\",\"\",\" ; double\",\" c = [1, 2, 3, 4d]\",\"\",\" ; complex double\",\" d = [1, 2, 3, 4di]\",\"\",\" ; invalid\",\" e = [1, 2, 3, plot()]\",\"\",\" ; ignore if element has Null\",\" f = [1, 2, 3, !null, 4, 5]\",\"\",\" ; no nested arrays, just promoted\",\" g = [1, 2, 3, [1, 2, 3, 4d], 4, 5]\",\"\",\" ; array of lists\",\" h = [list(), list()]\",\"\",\" ; array of ENVIRasters\",\" i = [ENVIRaster(), ENVIRaster()]\",\"\",\" ; array of any\",\" j = [ENVIRaster(), plot()]\",\"end\"]}]}","types.arrays.edge-cases.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.arrays.edge-cases.spec.ts\",\"tests\":[{\"name\":\"array creation using edge cases that failed\",\"code\":[\"pro array_creation\",\" compile_opt idl2\",\"\",\" ; array of number\",\" a = [where(x)]\",\"end\"]},{\"name\":\"scalars or arrays can be used interchangeably\",\"code\":[\"pro array_creation\",\" compile_opt idl2\",\" e = envi()\",\" r = e.openRaster() ; scalar or array ENVIRaster\",\" ; array of ENVIRaster\",\" arr = [r]\",\"end\"]},{\"name\":\"allow all objects as long as no structures or all structures\",\"code\":[\"pro array_creation\",\" compile_opt idl2\",\" arr1 = [ENVIRaster(), ENVIMetaspectralRaster(), ENVISubsetRaster()]\",\" arr2 = [{}, {}]\",\"\",\" bad = [ENVIRaster(), ENVIMetaspectralRaster(), ENVISubsetRaster(), {}, 1]\",\"end\"]}]}","types.array-promotion.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.array-promotion.spec.ts\",\"tests\":[{\"name\":\"array promotion\",\"code\":[\";+\",\"; :Returns: ArrayPromotion\",\";\",\"; :Arguments:\",\"; a: bidirectional, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function test, a\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"compile_opt idl2\",\"\",\"; scalars\",\"scalar1 = test(1)\",\"\",\"; arrays\",\"array1 = test([1])\",\"array2 = test(bytarr(5))\",\"\",\"; either scalar or array\",\"c = made_up()\",\"either = test(c)\",\"\",\"end\"]}]}","types.from-foreach.spec.ts":"{\"suiteName\":\"Types from foreach loop\",\"fileName\":\"types.from-foreach.spec.ts\",\"tests\":[{\"name\":\"with type args 1\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]},{\"name\":\"with type args 2\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]},{\"name\":\"with non-index types returning original 1\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, String\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]},{\"name\":\"with non-index types returning original 2\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, Number\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]}]}","types.from-foreach.regression1.spec.ts":"{\"suiteName\":\"Types from foreach loop regression tests\",\"fileName\":\"types.from-foreach.regression1.spec.ts\",\"tests\":[{\"name\":\"with bad syntax\",\"code\":[\"pro \",\";+\",\"; :Arguments:\",\"; item: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\" ; item is bad\",\" foreach val, item, key do print, val\",\"end\"]}]}","types.from-functions.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-functions.spec.ts\",\"tests\":[{\"name\":\"functions\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = ENVISubsetRaster()\",\"\",\" b = ENVITask('subsetraster')\",\"\",\" c = obj_new('envitask')\",\"\",\" d = keyword_set(5)\",\"\",\" e = dictionary()\",\"\",\" f = ENVITensorFlowModel()\",\"\",\" g = IDLTask('MyTask')\",\"\",\"end\"]},{\"name\":\"functions with other strings\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = ENVITask(\\\"subsetraster\\\")\",\"\",\" b = ENVITask(`subsetraster`)\",\"\",\" c = obj_new(\\\"envitask\\\")\",\"\",\" d = obj_new(`envitask`)\",\"\",\" e = IDLTask(\\\"MyTask\\\")\",\"\",\" f = IDLTask(`MyTask`)\",\"\",\"end\"]}]}","types.from-numbers.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-numbers.spec.ts\",\"tests\":[{\"name\":\"numbers\",\"code\":[\"pro pro4\",\"compile_opt idl2\",\"\",\"; byte\",\"byte1 = 0b\",\"byte2 = 0ub\",\"\",\"; integer\",\"int1 = 0s\",\"\",\"; compile option\",\"compOptLong = 0\",\"\",\"; uint\",\"uint1 = 0u\",\"uint2 = 0us\",\"\",\"; long\",\"long1 = 0l\",\"\",\"; ulong\",\"ulong1 = 0ul\",\"\",\"; long64\",\"long641 = 0ll\",\"\",\"; ulong64\",\"ulong641 = 0ull\",\"\",\"; float\",\"float1 = 1.\",\"float2 = .1\",\"float3 = 1.1\",\"float4 = 10e\",\"float5 = 10e5\",\"float6 = 10.e-3\",\"float7 = .1e+12\",\"float8 = 2.3e12\",\"\",\"; double\",\"double0 = 1d\",\"double1 = 1.d\",\"double2 = .1d\",\"double3 = 1.1d\",\"double4 = 10d\",\"double5 = 10d5\",\"double6 = 10.d-3\",\"double7 = .1d+12\",\"double8 = 2.3d12\",\"\",\"; binary\",\"binary1 = '10101'b\",\"binary2 = \\\"10101\\\"b\",\"\",\"; hex\",\"hex1 = '10101'x\",\"hex2 = '7FFF'XS\",\"hex3 = '8FFF'XS\",\"hex4 = \\\"10101\\\"x\",\"hex5 = 0x\",\"hex6 = 0x7FFF\",\"\",\"; octal\",\"octal1 = \\\"36\",\"octal2 = \\\"36b\",\"octal3 = \\\"345ull\",\"octal4 = '10101'o\",\"octal5 = \\\"10101\\\"o\",\"octal6 = 0o\",\"octal7 = 0o7FFF\",\"end\"]},{\"name\":\"numbers with no compile opt\",\"code\":[\"pro pro1\",\"compile_opt\",\"; compile option\",\"compOptInt = 0\",\"end\"]},{\"name\":\"numbers with float64 compile opt\",\"code\":[\"pro pro2\",\"compile_opt float64\",\"; compile option\",\"compOptDouble = 0\",\"\",\"; float\",\"float1 = 1.\",\"float2 = .1\",\"float3 = 1.1\",\"float4 = 10e\",\"float5 = 10e5\",\"float6 = 10.e-3\",\"float7 = .1e+12\",\"float8 = 2.3e12\",\"end\"]},{\"name\":\"numbers with idl3 compile opt\",\"code\":[\"pro pro3\",\"compile_opt idl3\",\"; compile option\",\"compOptDouble = 0\",\"\",\"; float\",\"float1 = 1.\",\"float2 = .1\",\"float3 = 1.1\",\"float4 = 10e\",\"float5 = 10e5\",\"float6 = 10.e-3\",\"float7 = .1e+12\",\"float8 = 2.3e12\",\"end\"]}]}","types.from-numbers-complex1.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-numbers-complex1.spec.ts\",\"tests\":[{\"name\":\"complex numbers using \\\"i\\\"\",\"code\":[\"pro pro5\",\"compile_opt idl2\",\"\",\"; byte\",\"byte1 = 0bi\",\"byte2 = 0ubi\",\"\",\"; integer\",\"int1 = 0si\",\"\",\"; compile option\",\"compOptLong = 0i\",\"\",\"; uint\",\"uint1 = 0ui\",\"uint2 = 0usi\",\"\",\"; long\",\"long1 = 0li\",\"\",\"; ulong\",\"ulong1 = 0uli\",\"\",\"; long64\",\"long641 = 0lli\",\"\",\"; ulong64\",\"ulong641 = 0ulli\",\"\",\"; float\",\"float1 = 1.i\",\"float2 = .1i\",\"float3 = 1.1i\",\"float4 = 10ei\",\"float5 = 10e5i\",\"float6 = 10.e-3i\",\"float7 = .1e+12i\",\"float8 = 2.3e12i\",\"\",\"; double\",\"double0 = 1di\",\"double1 = 1.di\",\"double2 = .1di\",\"double3 = 1.1di\",\"double4 = 10di\",\"double5 = 10d5i\",\"double6 = 10.d-3i\",\"double7 = .1d+12i\",\"double8 = 2.3d12i\",\"end\"]}]}","types.from-numbers-complex2.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-numbers-complex2.spec.ts\",\"tests\":[{\"name\":\"complex numbers using \\\"j\\\"\",\"code\":[\"pro pro6\",\"compile_opt idl2\",\"\",\"; byte\",\"byte1 = 0bj\",\"byte2 = 0ubj\",\"\",\"; jnteger\",\"jnt1 = 0sj\",\"\",\"; compjle optjon\",\"compOptLong = 0j\",\"\",\"; ujnt\",\"ujnt1 = 0uj\",\"ujnt2 = 0usj\",\"\",\"; long\",\"long1 = 0lj\",\"\",\"; ulong\",\"ulong1 = 0ulj\",\"\",\"; long64\",\"long641 = 0llj\",\"\",\"; ulong64\",\"ulong641 = 0ullj\",\"\",\"; float\",\"float1 = 1.j\",\"float2 = .1j\",\"float3 = 1.1j\",\"float4 = 10ej\",\"float5 = 10e5j\",\"float6 = 10.e-3j\",\"float7 = .1e+12j\",\"float8 = 2.3e12j\",\"\",\"; double\",\"double0 = 1dj\",\"double1 = 1.dj\",\"double2 = .1dj\",\"double3 = 1.1dj\",\"double4 = 10dj\",\"double5 = 10d5j\",\"double6 = 10.d-3j\",\"double7 = .1d+12j\",\"double8 = 2.3d12j\",\"end\"]}]}","types.from-properties.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-properties.spec.ts\",\"tests\":[{\"name\":\"properties\",\"code\":[\";+\",\"; :Arguments:\",\"; a: in, required, ENVIRaster\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4, a\",\" compile_opt idl2\",\"\",\" ; properties\",\" p1 = a.metadata\",\" p2 = p1.count\",\" p3 = (a.metadata)\",\" p4 = a.metadata.count\",\"end\"]}]}","types.from-properties2.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-properties2.spec.ts\",\"tests\":[{\"name\":\"properties of anonymous structures\",\"code\":[\"pro pro4\",\" compile_opt idl2\",\" a = {a: 'string', $\",\" b: `string`}\",\"\",\" ; properties\",\" p1 = a.a\",\" p2 = p1.length\",\" p3 = (a.b)\",\" p4 = a.b\",\"end\"]}]}","types.from-type-of-arg.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-type-of-arg.spec.ts\",\"tests\":[{\"name\":\"type-of-arg case without args (default to first)\",\"code\":[\";+\",\"; :Returns: TypeOfArg\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"\",\"string = myfunc('string')\",\"any = myfunc()\",\"float = myfunc(1.0)\",\"array = myfunc([1, 2, 3])\",\"end\"]},{\"name\":\"type-of-arg case specifying arg\",\"code\":[\";+\",\"; :Returns: TypeOfArg<0>\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"\",\"string = myfunc('string')\",\"any = myfunc()\",\"float = myfunc(1.0)\",\"array = myfunc([1, 2, 3])\",\"end\"]},{\"name\":\"type-of-arg case invalid arg uses any\",\"code\":[\";+\",\"; :Returns: TypeOfArg<2>\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"\",\"string = myfunc('string')\",\"any = myfunc()\",\"float = myfunc(1.0)\",\"array = myfunc([1, 2, 3])\",\"end\"]},{\"name\":\"type-of-arg case non-number index\",\"code\":[\";+\",\"; :Returns: TypeOfArg\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\"; main level\",\"compile_opt idl2\",\"\",\"string = myfunc('string')\",\"any = myfunc()\",\"float = myfunc(1.0)\",\"array = myfunc([1, 2, 3])\",\"end\"]}]}","types.from-type-args.edge-cases1.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.from-type-args.edge-cases1.spec.ts\",\"tests\":[{\"name\":\"type without type args\",\"code\":[\";+\",\"; :Arguments:\",\"; item: in, required, List<>\",\"; Placeholder docs for argument, keyword, or property\",\";-\",\"pro foreach, item\",\" compile_opt idl2\",\"end\"]}]}","types.indexing.arrays.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.arrays.spec.ts\",\"tests\":[{\"name\":\"indexing arrays\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro arrays, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.dictionaries.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.dictionaries.spec.ts\",\"tests\":[{\"name\":\"dictionaries\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, Dictionary\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro dictionaries, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.hashes.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.hashes.spec.ts\",\"tests\":[{\"name\":\"hashes\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, Hash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro34, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.lists.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.lists.spec.ts\",\"tests\":[{\"name\":\"lists\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, List\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro lists, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.ordered-hashes.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.ordered-hashes.spec.ts\",\"tests\":[{\"name\":\"ordered hashes\",\"code\":[\";+\",\"; :Returns:\",\"; Number\",\";\",\";-\",\"function myfunc\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; Array\",\";\",\";-\",\"function myfunc2\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Arguments:\",\"; arg1: in, required, OrderedHash\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, any\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro ordered_hashes, arg1, arg2, arg3, arg4, arg5, arg6\",\" compile_opt idl3\",\"\",\" ; type args\",\" c = arg1[0]\",\"\",\" ; return array of type args\",\" d = arg1[arg2]\",\"\",\" ; return array\",\" e = arg1[*]\",\"\",\" ; return array\",\" f = arg1[0, 1, *]\",\"\",\" ; return type args\",\" g = arg1[myfunc()]\",\"\",\" ; return array\",\" h = arg1[myfunc2()]\",\"\",\" ; type args\",\" i = arg1[0, 1, 2]\",\"\",\" ; return array\",\" j = arg1[0, 1, myfunc2()]\",\"\",\" ; return array\",\" k = arg1[0 : -1 : 1]\",\"\",\" ; return array\",\" l = arg1[0, 1, *]\",\"\",\" ; return type args\",\" m = arg1[-1]\",\"\",\" ; any\",\" n = arg3[0]\",\"\",\" ; array of any\",\" o = arg3[myfunc2()]\",\"\",\" ; return array\",\" p = arg1[0, myfunc2(), 1]\",\"\",\" ; return array\",\" q = arg1[[1, 2, 3]]\",\"\",\" ; return type args\",\" r = arg1[1 + 2]\",\"\",\" ; return array\",\" s = arg1[1 + myfunc2()]\",\"\",\" ; return any\",\" t = arg1[plot()]\",\"\",\" ; return any\",\" u = arg1[1j]\",\"\",\" ; return any\",\" v = arg1[1i]\",\"\",\" ; return any\",\" w = arg1[1di]\",\"\",\" ; return any\",\" x = arg1[1dj]\",\"\",\" ; merge type args\",\" y = arg1 + arg3\",\"\",\" ; merge type args\",\" z = arg1 + arg4 + 1l\",\"\",\" ; merge type args\",\" a2 = arg1 + arg4 + 1\",\"\",\" ; merge type args\",\" b2 = arg1 + arg4 + arg5\",\"\",\" ; any\",\" c2 = arg1[arg6]\",\"\",\" ; any\",\" d2 = arg1 + arg4 + arg6\",\"end\"]}]}","types.indexing.properties.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.properties.spec.ts\",\"tests\":[{\"name\":\"property indexing\",\"code\":[\"pro mypro1\",\" compile_opt idl2\",\" ; number or array of numbers\",\" index = where('5' eq fn)\",\" ; any\",\" x = (!null).(1)[index]\",\"end\",\"\"]}]}","types.indexing.edge-cases.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.indexing.edge-cases.spec.ts\",\"tests\":[{\"name\":\"indexing compound types\",\"code\":[\"compile_opt idl2\",\"; should be number\",\"rb_match = (where(5 eq [1, 2, 3, 4, 5]))[0]\",\"end\",\"\"]},{\"name\":\"scalar with array\",\"code\":[\"compile_opt idl2\",\"polyColors = 5l\",\"array1 = polyColors[idx : nMax]\",\"array2 = polyColors[[5 : 15: 1]]\",\"end\",\"\"]}]}","types.keywords.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.keywords.spec.ts\",\"tests\":[{\"name\":\"output or bidirectional keywords\",\"code\":[\";+\",\"; :Description:\",\"; Constructor\",\";\",\"; :Returns:\",\"; myclass\",\";\",\";-\",\"function myclass::Init\",\" compile_opt idl2\",\"\",\" return, 1\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw: out, optional, Array\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myclass::method, kw = kw\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw: out, optional, ENVIRaster\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro myclass::method, kw = kw\",\" compile_opt idl2\",\"end\",\"\",\";+\",\"; :Description:\",\"; Class definition procedure\",\";\",\";-\",\"pro myclass__define\",\" compile_opt idl2\",\"\",\" struct = {myclass}\",\"end\",\"\",\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Keywords:\",\"; kw: out, optional, Long\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function myfunc, kw = kw\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\";+\",\"; :Keywords:\",\"; kw: out, optional, Byte\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro mypro, kw = kw\",\" compile_opt idl2\",\"\",\"end\",\"\",\"; main level program\",\"compile_opt idl2\",\"\",\"; procedures\",\"mypro, kw = a\",\"\",\"; functions\",\"!null = myfunc(kw = b)\",\"\",\"; make class for methods\",\"var = myclass()\",\"\",\"; procedure methods\",\"var.method, kw = c\",\"\",\"; function methods\",\"!null = var.method(kw = d)\",\"end\"]}]}","types.operations.structures.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.structures.spec.ts\",\"tests\":[{\"name\":\"structure operations\",\"code\":[\"pro struct_checks\",\"compile_opt idl2\",\"\",\"str = {a: 42}\",\"\",\"a = 1 + str\",\"\",\"b = str + {a: 42}\",\"\",\"c = str + list()\",\"\",\"d = str + hash()\",\"\",\"e = str + orderedhash()\",\"\",\"f = str + dictionary()\",\"end\"]}]}","types.operations.list.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.list.spec.ts\",\"tests\":[{\"name\":\"list operations\",\"code\":[\"pro list_checks\",\"compile_opt idl2\",\"\",\"a = 1 + list()\",\"\",\"b = list() + list()\",\"\",\"c = list() + hash()\",\"\",\"d = list() + orderedhash()\",\"\",\"e = list() + dictionary()\",\"end\"]}]}","types.operations.hash.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.hash.spec.ts\",\"tests\":[{\"name\":\"hash operations\",\"code\":[\"pro hash_checks\",\"compile_opt idl2\",\"\",\"a = 1 + hash()\",\"\",\"b = hash() + list()\",\"\",\"c = hash() + hash()\",\"\",\"d = hash() + orderedhash()\",\"\",\"e = hash() + dictionary()\",\"end\"]}]}","types.operations.ordered-hash.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.ordered-hash.spec.ts\",\"tests\":[{\"name\":\"ordered hash operations\",\"code\":[\"pro orderedhash_checks\",\"compile_opt idl2\",\"\",\"a = 1 + orderedhash()\",\"\",\"b = orderedhash() + list()\",\"\",\"c = orderedhash() + hash()\",\"\",\"d = orderedhash() + orderedhash()\",\"\",\"e = orderedhash() + dictionary()\",\"end\"]}]}","types.operations.dictionary.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.operations.dictionary.spec.ts\",\"tests\":[{\"name\":\"dictionary operations\",\"code\":[\"pro dictionary_checks\",\"compile_opt idl2\",\"\",\"a = 1 + dictionary()\",\"\",\"b = dictionary() + list()\",\"\",\"c = dictionary() + hash()\",\"\",\"d = dictionary() + orderedhash()\",\"\",\"e = dictionary() + dictionary()\",\"end\"]}]}","types.parsing-checks.1.spec.ts":"{\"suiteName\":\"Cases to make sure we always parse our types correctly\",\"fileName\":\"types.parsing-checks.1.spec.ts\",\"tests\":[{\"name\":\"for normal cases\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Pointer>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Number | String\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, Hash | List>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg7: in, required, Hash | List | List>\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro type_parsing_test, arg1, arg2, arg3, arg4, arg5, arg6, arg7\",\" compile_opt idl3\",\"\",\"end\"]}]}","types.pointer-de-ref.1.spec.ts":"{\"suiteName\":\"Get types correctly from pointer de-reference\",\"fileName\":\"types.pointer-de-ref.1.spec.ts\",\"tests\":[{\"name\":\"for normal cases\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array>\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, Pointer | String\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg6: in, required, Pointer | Pointer\",\"; Placeholder docs for argument, keyword, or property\",\"; arg7: in, required, Pointer | Pointer\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pointers, arg1, arg2, arg3, arg4, arg5, arg6, arg7\",\" compile_opt idl3\",\"\",\" ; number\",\" a = *arg1\",\"\",\" ; enviraster\",\" b = *arg3[0]\",\"\",\" ; and, unable to index\",\" c = arg1[0]\",\"\",\" ; any, unable to de-reference\",\" d = *5\",\"\",\" ; any, ambiguous de-reference\",\" e = *arg4\",\"\",\" ; any\",\" f = *arg5\",\"\",\" ; union of type args\",\" g = *arg6\",\"\",\" ; union of type args, dont show arg7 more string more than once\",\" g = *arg7\",\"end\"]}]}","types.promotion1.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.promotion1.spec.ts\",\"tests\":[{\"name\":\"type promotion\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\"; :Arguments:\",\"; a: in, required, Number\",\"; Placeholder docs for argument, keyword, or property\",\"; b: in, required, ComplexNumber\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"function most_cases, a, b\",\" compile_opt idl2\",\"\",\" byte = 's' + 1b\",\"\",\" int = 's' + 1s\",\"\",\" uint = 's' + 1us\",\"\",\" long = 's' + 1l\",\"\",\" ulong = 's' + 1ul\",\"\",\" long64 = 's' + 1ll\",\"\",\" ulong64 = 's' + 1ull\",\"\",\" float1 = 's' + 1.\",\" float2 = 's' + 1e\",\"\",\" double = 's' + 1d\",\"\",\" biginteger = 's' + BigInteger(5)\",\"\",\" number = 's' + a\",\"\",\" complexfloat = 's' + 1.i\",\"\",\" complexdouble = 's' + 1di\",\" complexdouble = 's' + 1dj\",\"\",\" complexnumber1 = 's' + a + 1di + 1dj\",\" complexnumber2 = a + b\",\"\",\" return, 1\",\"end\"]}]}","types.strings.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.strings.spec.ts\",\"tests\":[{\"name\":\"strings\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = 'single quote'\",\"\",\" b = \\\"double quote\\\"\",\"\",\" c = `literal string`\",\"\",\"end\"]}]}","types.ternary.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.ternary.spec.ts\",\"tests\":[{\"name\":\"ternary\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" ; long or envi\",\" a = !true ? 5 + 15 : envi()\",\"\",\" ; long or string\",\" b = !true ? 5 + 15 : 'string'\",\"\",\" ; string\",\" c = !true ? 'string' : 'false'\",\"\",\" ; number\",\" d = !true ? 5 : 6\",\"\",\" ; any\",\" e = !true ? 5 \",\"\",\" ; any\",\" f = !true ? 5 :\",\"\",\"end\"]}]}","types.variables.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.variables.spec.ts\",\"tests\":[{\"name\":\"variables\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = ENVISubsetRaster()\",\"\",\" b = a\",\"end\"]}]}","types.static-classes.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.static-classes.spec.ts\",\"tests\":[{\"name\":\"named static classes methods/properties\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = IDL_Number.ndim\",\" b = envi.openRaster()\",\" any1 = image ; nothing\",\"end\"]}]}","types.structure-names.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.structure-names.spec.ts\",\"tests\":[{\"name\":\"named structures\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = {ENVIRaster}\",\"\",\" b = {!map}\",\"end\"]}]}","types.structure-anonymous.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.structure-anonymous.spec.ts\",\"tests\":[{\"name\":\"anonymous structures\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = {a: 'string', $\",\" b: `string`}\",\"\",\"end\"]}]}","types.system-variables.spec.ts":"{\"suiteName\":\"Types from\",\"fileName\":\"types.system-variables.spec.ts\",\"tests\":[{\"name\":\"the !null system variable\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = !null\",\"end\"]},{\"name\":\"system variables that are structures\",\"code\":[\"pro myPro\",\" compile_opt idl2\",\"\",\" a = !x\",\"end\"]}]}"},"auto-outline-tests":{"ex-1.spec.ts":"{\"suiteName\":\"Extracts outline\",\"fileName\":\"ex-1.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/awesomerasterintersection.pro\"}]}","ex-2.spec.ts":"{\"suiteName\":\"Extracts outline with main\",\"fileName\":\"ex-2.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens and handle undefined\",\"file\":\"idl/test/hover-help/myfunc.pro\"}]}","ex-3.spec.ts":"{\"suiteName\":\"Extracts outline\",\"fileName\":\"ex-3.spec.ts\",\"tests\":[{\"name\":\"extract correct tokens with multiple parent routines\",\"file\":\"idl/test/hover-help/mypro.pro\"}]}"},"auto-semantic-token-tests":{"basic.spec.ts":"{\"suiteName\":\"Extracts semantic tokens\",\"fileName\":\"basic.spec.ts\",\"tests\":[{\"name\":\"for basic case\",\"code\":[\"compile_opt idl2\",\"a = envi.api_version\",\"!null = envi.openRaster('somefile.dat')\",\"end\"]}]}","complex.spec.ts":"{\"suiteName\":\"Extracts semantic tokens\",\"fileName\":\"complex.spec.ts\",\"tests\":[{\"name\":\"for complex case with out-of order and same ref\",\"code\":[\"compile_opt idl2\",\"IDLgrVolume.AddToNotebookMap\",\"!null = ENVI.displayinnotebookmap + ENVI.api_version\",\"\",\"IDLgrVolume.AddToNotebookMap\",\"ENVI.displayInNotebookMap\",\"end\"]}]}"},"auto-task-parsing-tests":{"envi1.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"envi1.spec.ts\",\"tests\":[{\"name\":\"envi\",\"file\":\"idl/test/task-parsing/BuildMosaicRaster.task\"}]}","envi2.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"envi2.spec.ts\",\"tests\":[{\"name\":\"envi\",\"file\":\"idl/test/task-parsing/ExportRasterToCADRG.task\"}]}","envi3.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"envi3.spec.ts\",\"tests\":[{\"name\":\"envi\",\"file\":\"idl/test/task-parsing/PointCloudFeatureExtraction.task\"}]}","envi4.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"envi4.spec.ts\",\"tests\":[{\"name\":\"envi\",\"file\":\"idl/test/task-parsing/SetRasterMetadata.task\"}]}","idl1.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"idl1.spec.ts\",\"tests\":[{\"name\":\"idl\",\"file\":\"idl/test/task-parsing/Download_S3_URL.task\"}]}","idl2.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"idl2.spec.ts\",\"tests\":[{\"name\":\"idl\",\"file\":\"idl/test/task-parsing/QueryAllTasks.task\"}]}","idl3.spec.ts":"{\"suiteName\":\"Correctly parse task file\",\"fileName\":\"idl3.spec.ts\",\"tests\":[{\"name\":\"idl\",\"file\":\"idl/test/task-parsing/QueryTask.task\"}]}"},"auto-assembler-tests":{"auto-doc.args.spec.ts":"{\"suiteName\":\"Verify arg formatting\",\"fileName\":\"auto-doc.args.spec.ts\",\"tests\":[{\"name\":\"matches arg definitions\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, Array\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, ARG3\",\" compile_opt idl3\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.basic.spec.ts":"{\"suiteName\":\"Verify doc formatting\",\"fileName\":\"auto-doc.basic.spec.ts\",\"tests\":[{\"name\":\"close and auto populate existing docs block\",\"code\":[\";+\",\";\",\"function myPro, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\" return, 42\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"capture default content and re-work\",\"code\":[\";+\",\"; Header\",\";-\",\"pro myPro\",\" compile_opt idl2\",\" print, 'Hello world'\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"add docs for procedures automatically\",\"code\":[\"pro myPro, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\" return, 42\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"add docs for functions automatically\",\"code\":[\"function myPro2, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\" return, 42\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"add docs for multiple routines at once\",\"code\":[\"pro myPro, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\"end\",\"\",\"function myPro2, a, c, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"\",\" return, 42\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"handle, and format correctly, multi-line headers\",\"code\":[\";+\",\"; :Something fancy:\",\"; Really cool information \",\"; sdf\",\";-\",\"pro test_things\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\" uses proper external name for keyword in auto-docs\",\"code\":[\"pro test_things2, a, b, kw2 = kw222\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\" for only arguments\",\"code\":[\"pro test_things2, a, b\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\" for only keywords\",\"code\":[\"pro test_things2, kw222=kw2, kw3 = kw3\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.example-code.spec.ts":"{\"suiteName\":\"Verify formatting\",\"fileName\":\"auto-doc.example-code.spec.ts\",\"tests\":[{\"name\":\"for example blocks moves\",\"code\":[\"; TODO: something\",\"pro test_things, a, b, c\",\" compile_opt idl2\",\"end\",\"\",\";+\",\"; :Description:\",\"; My favorite procedure\",\"; \",\"; \",\"; \",\"; :Examples:\",\"; \",\"; Open an image in ENVI and display in a notebook:\",\"; \",\"; ```idl\",\"; ; Start the application\",\"; e = envi(/headless)\",\"; \",\"; ; Open an input file\",\"; file = filepath('qb_boulder_msi', subdir = ['data'], $\",\"; root_dir = e.root_dir)\",\"; raster = e.openRaster(File)\",\"; \",\"; ; display in the current notebook cell\",\"; e.displayInNotebook, raster\",\"; ```\",\";-\",\"pro test_things2\",\" compile_opt idl2\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.complex2.spec.ts":"{\"suiteName\":\"Verify complex formatting\",\"fileName\":\"auto-doc.complex2.spec.ts\",\"tests\":[{\"name\":\"moves things correctly\",\"code\":[\"; TODO: something\",\"pro test_things, a, b, c\",\" compile_opt idl2\",\"end\",\"\",\";+\",\";-\",\"pro test_things2\",\" compile_opt idl2\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.complex3.spec.ts":"{\"suiteName\":\"Verify complex formatting\",\"fileName\":\"auto-doc.complex3.spec.ts\",\"tests\":[{\"name\":\"moves main level correctly\",\"code\":[\"; TODO: something\",\"pro test_things\",\"end\",\"\",\"compile_opt idl2\",\"\",\"test_things\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.complex4.spec.ts":"{\"suiteName\":\"Verify complex formatting\",\"fileName\":\"auto-doc.complex4.spec.ts\",\"tests\":[{\"name\":\"moves main level correctly\",\"code\":[\";+\",\"; :Description:\",\"; Function which will initialize the bdige_it object and start all bridges. When bridges are initialized\",\"; they are done so in parallel, but whe function will not return until every bridge is idle again.\",\";\",\"; :Params:\",\"; nbridges: in, required, type=int\",\"; The number of bridges that you want to create\",\";\",\"; :Keywords:\",\"; INIT : in, optional, type=strarr\",\"; Optional argument which allows you to pass in a string array of extra commands\",\"; to have each IDL_IDLBridge object execute upon creation.\",\"; MSG : in, optional, type=string\",\"; Optional argument to show the message prefix when a bridge process has completed for the TIME\",\"; keyword in bridge_it::run and bridge_it::run().\",\"; LOGDIR : in, optional, type=string\",\"; Specify the directory that the log file will be written to. The log file is just a text file with\",\"; all of the IDL Console output from each child process.\",\"; NREFRESH : in, optional, type=long\",\"; Specify the number of bridge processes to execute before closing and re-starting the\",\"; child process. Necessary for some ENVI routines so that we don't have memory fragmentation\",\"; regarding opening lots of small rasters.\",\"; PREFIX : in, optional, type=string, default='_KW_'\",\"; This optional keyword specifies the prefix which is used to differentiate between arguments and\",\"; keywords when it comes time to parse the arguments and keyword that will be passed into a routine.\",\";\",\"; :Author: Zachary Norman - GitHub: [znorman-harris](https://github.com/znorman-harris)\",\";\",\";-\",\"function bridge_it::Init, nbridges, INIT = init, MSG = msg, LOGDIR = logdir, NREFRESH = nrefresh, PREFIX = prefix\",\" compile_opt idl2, hidden\",\" on_error, 2\",\"\",\" return, 1\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.non-idl-display-names.spec.ts":"{\"suiteName\":\"Verify type formatting uses display names\",\"fileName\":\"auto-doc.non-idl-display-names.spec.ts\",\"tests\":[{\"name\":\"matches arg definitions\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, enviraster\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idl_variable\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, plot\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, arg3\",\" compile_opt idl3\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.only.spec.ts":"{\"suiteName\":\"Only use AutoDoc\",\"fileName\":\"auto-doc.only.spec.ts\",\"tests\":[{\"name\":\"and leave everything else the same\",\"code\":[\"function dist,n,m ;Return a rectangular array in which each pixel = euclidian\",\";distance from the origin.\",\"compile_opt idl2\",\"\",\"on_error,2 ;Return to caller if an error occurs\",\"\",\"n1 = n[0]\",\"m1 = (n_elements(m) le 0) ? n1 : m[0]\",\"x=findgen(n1) ;Make a row\",\"x = (x < (n1-x)) ^ 2 ;column squares\",\"\",\"a = FLTARR(n1,m1,/NOZERO) ;Make array\",\"\",\"for i=0L, m1/2 do begin ;Row loop\",\"y = sqrt(x + i^2.) ;Euclidian distance\",\"a[0,i] = y ;Insert the row\",\"if i ne 0 then a[0, m1-i] = y ;Symmetrical\",\"endfor\",\"return,a\",\"end\"],\"config\":{\"autoDoc\":true,\"styleAndFormat\":false}}]}","auto-doc.only2.spec.ts":"{\"suiteName\":\"Only use AutoDoc\",\"fileName\":\"auto-doc.only2.spec.ts\",\"tests\":[{\"name\":\"and dont fix problems\",\"code\":[\"pro test, a, b, c\",\"end\",\"\",\"test\",\"end\"],\"config\":{\"autoDoc\":true,\"styleAndFormat\":false,\"autoFix\":false}}]}","auto-doc.parameters.spec.ts":"{\"suiteName\":\"Verify parameter formatting\",\"fileName\":\"auto-doc.parameters.spec.ts\",\"tests\":[{\"name\":\"sort arguments by appearance and add bad at the end\",\"code\":[\";+\",\"; :Args:\",\"; a: in, required, int, private\",\"; Some cool statement\",\"; b: in, required, string\",\"; Some cool statement\",\"; c: in, required, int, private\",\"; Some cool statement\",\";\",\";-\",\"pro myPro, a, c\",\" compile_opt idl2\",\" print, 'Hello world'\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"sort keywords alphabetically and add bad at the end\",\"code\":[\";+\",\"; :Keywords:\",\"; kw2: in, required, int\",\"; Some cool statement\",\"; kw: in, required, string\",\"; Some cool statement across\",\";\",\"; multiple lines\",\"; kw1: in, required, string\",\"; Some cool statement across\",\";\",\";-\",\"pro myPro, kw1 = kw1, kw=kw\",\" compile_opt idl2\",\" print, 'Hello world'\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.order-args.spec.ts":"{\"suiteName\":\"Verify arg ordering\",\"fileName\":\"auto-doc.order-args.spec.ts\",\"tests\":[{\"name\":\"matches the argument definition\",\"code\":[\";+\",\"; :Arguments:\",\"; a01: in, required, any\",\"; Placeholder docs for argument or keyword\",\"; a02: in, required, array\",\"; Placeholder docs for argument or keyword\",\"; a03: in, required, bigint\",\"; Placeholder docs for argument or keyword\",\"; a04: in, required, biginteger\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro my_thing, $\",\" a03, a04, a01, a02\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.task-types.spec.ts":"{\"suiteName\":\"Verify type formatting for\",\"fileName\":\"auto-doc.task-types.spec.ts\",\"tests\":[{\"name\":\"ENVI and IDL Tasks\",\"code\":[\";+\",\"; :Arguments:\",\"; arg1: in, required, envitask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg2: in, required, idltask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg3: in, required, ENVITask | ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg4: in, required, IDLTask\",\"; Placeholder docs for argument, keyword, or property\",\"; arg5: in, required, ENVITask\",\"; Placeholder docs for argument, keyword, or property\",\";\",\";-\",\"pro pro3, arg1, arg2, arg3, arg4, arg5\",\" compile_opt idl3\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.types.spec.ts":"{\"suiteName\":\"Verify type formatting\",\"fileName\":\"auto-doc.types.spec.ts\",\"tests\":[{\"name\":\"parses and gives normalized appearance for all IDL types\",\"code\":[\";+\",\"; :Arguments:\",\"; a01: in, required, any\",\"; Placeholder docs for argument or keyword\",\"; a02: in, required, array\",\"; Placeholder docs for argument or keyword\",\"; a03: in, required, bigint\",\"; Placeholder docs for argument or keyword\",\"; a04: in, required, biginteger\",\"; Placeholder docs for argument or keyword\",\"; a05: in, required, binary\",\"; Placeholder docs for argument or keyword\",\"; a06: in, required, bool\",\"; Placeholder docs for argument or keyword\",\"; a07: in, required, boolean\",\"; Placeholder docs for argument or keyword\",\"; a08: in, required, byte\",\"; Placeholder docs for argument or keyword\",\"; a09: in, required, complex\",\"; Placeholder docs for argument or keyword\",\"; a10: in, required, dcomplex\",\"; Placeholder docs for argument or keyword\",\"; a11: in, required, doublecomplex\",\"; Placeholder docs for argument or keyword\",\"; a12: in, required, dict\",\"; Placeholder docs for argument or keyword\",\"; a13: in, required, dictionary\",\"; Placeholder docs for argument or keyword\",\"; a14: in, required, float64\",\"; Placeholder docs for argument or keyword\",\"; a15: in, required, double\",\"; Placeholder docs for argument or keyword\",\"; a16: in, required, float32\",\"; Placeholder docs for argument or keyword\",\"; a17: in, required, float\",\"; Placeholder docs for argument or keyword\",\"; a18: in, required, hash\",\"; Placeholder docs for argument or keyword\",\"; a19: in, required, hex\",\"; Placeholder docs for argument or keyword\",\"; a20: in, required, int\",\"; Placeholder docs for argument or keyword\",\"; a21: in, required, integer\",\"; Placeholder docs for argument or keyword\",\"; a22: in, required, list\",\"; Placeholder docs for argument or keyword\",\"; a23: in, required, long\",\"; Placeholder docs for argument or keyword\",\"; a24: in, required, long64\",\"; Placeholder docs for argument or keyword\",\"; a25: in, required, null\",\"; Placeholder docs for argument or keyword\",\"; a26: in, required, number\",\"; Placeholder docs for argument or keyword\",\"; a27: in, required, class\",\"; Placeholder docs for argument or keyword\",\"; a28: in, required, object\",\"; Placeholder docs for argument or keyword\",\"; a29: in, required, octal\",\"; Placeholder docs for argument or keyword\",\"; a30: in, required, orderedhash\",\"; Placeholder docs for argument or keyword\",\"; a31: in, required, pointer\",\"; Placeholder docs for argument or keyword\",\"; a32: in, required, string\",\"; Placeholder docs for argument or keyword\",\"; a33: in, required, structure\",\"; Placeholder docs for argument or keyword\",\"; a34: in, required, uint\",\"; Placeholder docs for argument or keyword\",\"; a35: in, required, unsignedint\",\"; Placeholder docs for argument or keyword\",\"; a36: in, required, unsignedinteger\",\"; Placeholder docs for argument or keyword\",\"; a37: in, required, ulong\",\"; Placeholder docs for argument or keyword\",\"; a38: in, required, unsignedlong\",\"; Placeholder docs for argument or keyword\",\"; a39: in, required, ulong64\",\"; Placeholder docs for argument or keyword\",\"; a40: in, required, unsignedlong64\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro my_thing, $\",\" a01, a02, a03, a04, a05, a06, a07, a08, a09, a10, $\",\" a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, $\",\" a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, $\",\" a31, a32, a33, a34, a35, a36, a37, a38, a39, a40\",\" compile_opt idl2\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.non-idl-doc.spec.ts":"{\"suiteName\":\"Verify doc formatting\",\"fileName\":\"auto-doc.non-idl-doc.spec.ts\",\"tests\":[{\"name\":\"for non IDL Doc styled docs\",\"code\":[\";+\",\"; NAME:\",\"; DIST\",\";\",\"; PURPOSE:\",\"; Create a rectangular array in which each element is proportional\",\"; to its frequency. This array may be used for a variety\",\"; of purposes, including frequency-domain filtering and\",\"; making pretty pictures.\",\";\",\"; CATEGORY:\",\"; Signal Processing.\",\";\",\"; CALLING SEQUENCE:\",\"; Result = DIST(N [, M])\",\";\",\"; INPUTS:\",\"; N = number of columns in result.\",\"; M = number of rows in result. If omitted, N is used to return\",\"; a square array.\",\";\",\"; OUTPUTS:\",\"; Returns an (N,M) floating array in which:\",\";\",\"; R(i,j) = SQRT(F(i)^2 + G(j)^2) where:\",\"; F(i) = i IF 0 <= i <= n/2\",\"; = n-i IF i > n/2\",\"; G(i) = i IF 0 <= i <= m/2\",\"; = m-i IF i > m/2\",\";\",\"; SIDE EFFECTS:\",\"; None.\",\";\",\"; RESTRICTIONS:\",\"; None.\",\";\",\"; PROCEDURE:\",\"; Straightforward. The computation is done a row at a time.\",\";\",\"; MODIFICATION HISTORY:\",\"; Very Old.\",\"; SMR, March 27, 1991 - Added the NOZERO keyword to increase efficiency.\",\"; (Recomended by Wayne Landsman)\",\"; DMS, July, 1992. - Added M parameter to make non-square arrays.\",\"; CT, RSI, March 2000: Changed i^2 to i^2. to avoid overflow.\",\";-\",\"function dist,n,m ;Return a rectangular array in which each pixel = euclidian\",\" ;distance from the origin.\",\"compile_opt idl2\",\"\",\"on_error,2 ;Return to caller if an error occurs\",\"\",\"n1 = n[0]\",\"m1 = (n_elements(m) le 0) ? n1 : m[0]\",\"x=findgen(n1) ;Make a row\",\"x = (x < (n1-x)) ^ 2 ;column squares\",\"\",\"a = FLTARR(n1,m1,/NOZERO) ;Make array\",\"\",\"for i=0L, m1/2 do begin ;Row loop\",\" y = sqrt(x + i^2.) ;Euclidian distance\",\" a[0,i] = y ;Insert the row\",\" if i ne 0 then a[0, m1-i] = y ;Symmetrical\",\"endfor\",\"return,a\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.format-keywords.spec.ts":"{\"suiteName\":\"Apply keyword formatting\",\"fileName\":\"auto-doc.format-keywords.spec.ts\",\"tests\":[{\"name\":\"so docs match code style\",\"code\":[\";+\",\"; :Description:\",\"; My sample procedure with default \\\"modern\\\" formatting\",\";\",\"; :Arguments:\",\"; arg1: in, required, Boolean\",\"; My favorite argument\",\"; arg2: in, optional, Boolean\",\"; My second favorite argument\",\";\",\"; :Keywords:\",\"; KW1: in, required, Boolean\",\"; My favorite keyword\",\"; KW2: in, optional, Boolean\",\"; My second favorite keyword\",\";\",\";-\",\"pro mypro_modern, arg1, arg2, kw1 = kw1, kw2 = kw2\",\" compile_opt idl2, hidden\",\"\",\" ;+ reference to our super cool and awesome plot\",\" a = plot(/test)\",\"\",\" ; sample if statement\",\" if !true then begin\",\" print, 42\",\" endif else begin\",\" print, 84\",\" endelse\",\"\",\" ; sample for loop\",\" foreach val, var, key do begin\",\"\",\" endforeach\",\"\",\" ; sample ENVI routine\",\" e = envi()\",\" r = ENVIRaster(metadata = meta) ; formatting matches docs\",\"\",\"end\"],\"config\":{\"autoDoc\":true,\"style\":{\"keywords\":\"lower\"}}}]}","auto-doc.structures.spec.ts":"{\"suiteName\":\"Generate structure docs\",\"fileName\":\"auto-doc.structures.spec.ts\",\"tests\":[{\"name\":\"to automatically add them\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"to do nothing without a class/structure definition routine\",\"code\":[\"pro pro4\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\" !null = {mystruct2, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"add missing properties and sort alphabetically with bad at the end\",\"code\":[\";+\",\"; :MyStruct:\",\"; propFake: any\",\"; Placeholder docs for argument or keyword\",\"; prop2: any\",\"; Placeholder docs for argument or keyword\",\";\",\";-\",\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct, inherits IDL_object, prop: 1, prop2: 4}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}},{\"name\":\"with no properties\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {MyStruct}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","auto-doc.structures.2.spec.ts":"{\"suiteName\":\"Generate structure docs\",\"fileName\":\"auto-doc.structures.2.spec.ts\",\"tests\":[{\"name\":\"and verify spacing for empty structures\",\"code\":[\"pro pro4__define\",\" compile_opt idl2\",\"\",\" !null = {struct1}\",\"\",\" !null = {struct2}\",\"\",\" !null = {struct3, prop: 'socool'}\",\"\",\"end\"],\"config\":{\"autoDoc\":true}}]}","format.after-main.spec.ts":"{\"suiteName\":\"Keep tokens after main level programs\",\"fileName\":\"format.after-main.spec.ts\",\"tests\":[{\"name\":\"example 1\",\"code\":[\"compile_opt idl2\",\"\",\"a = 5\",\"end\",\"; comment\",\"b = 17\"]}]}","format.after-line-continuation.spec.ts":"{\"suiteName\":\"Keep tokens after line continuations\",\"fileName\":\"format.after-line-continuation.spec.ts\",\"tests\":[{\"name\":\"example 1\",\"code\":[\"\",\"compile_opt idl2\",\"; thing\",\"a = $ something bad ;\",\" 5\",\"end\"]}]}","format.arrays.1.spec.ts":"{\"suiteName\":\"Verify array formatting\",\"fileName\":\"format.arrays.1.spec.ts\",\"tests\":[{\"name\":\"basic formatting\",\"code\":[\"compile_opt idl2\",\"\",\"a = [1,2,3,4,5]\",\"end\"]},{\"name\":\"line continuation 1\",\"code\":[\"compile_opt idl2\",\"\",\"a = [ $\",\" 1, $\",\" 2,$\",\" 3, $\",\" 4, $\",\" 5 $\",\"]\",\"end\"]},{\"name\":\"indexing and properties\",\"code\":[\"compile_opt idl2\",\"\",\"for xx = 0, numRows-1 do begin\",\"xRows[xx].Index = xCobs[xx].Index\",\"xRows[xx].Name = xCobs[xx].Name\",\"xRows[xx].Label = xCobs[xx].Label\",\"xRows[xx].SRS_Name = xCobs[xx].SRS_Name\",\"xRows[xx].Pos1 = xCobs[xx].Pos1\",\"xRows[xx].Dims1 = xCobs[xx].Dims1\",\"xRows[xx].Pos2 = xCobs[xx].Pos2\",\"xRows[xx].Dims2 = xCobs[xx].Dims2\",\"xRows[xx].Tm_Pos1 = xCobs[xx].Tm_Pos1\",\"xRows[xx].Tm_Pos2 = xCobs[xx].Tm_Pos2\",\"endfor\",\"\",\"end\"]},{\"name\":\"array indexing spacing\",\"code\":[\"overlaps.LOWER[sIdx] = ptr_new(segs[tSub[0] : tSub[2], tSub[3]])\"]},{\"name\":\"brackets for access (via overload)\",\"code\":[\"meta['band names'] = 'Awesome Label Regions'\"]},{\"name\":\"array after comma as argument\",\"code\":[\"compile_opt idl2\",\"\",\" inputValidator, hash( $\",\"'buffer', ['number', 'required'])\",\"\",\"end\"]}]}","format.assignment.1.spec.ts":"{\"suiteName\":\"Verify assignment formatting\",\"fileName\":\"format.assignment.1.spec.ts\",\"tests\":[{\"name\":\"multi-multi line assignment with operators looking correct\",\"code\":[\"compile_opt idl2\",\"\",\"a = 1 + $\",\" 2+ $\",\" 3 + $\",\" 4+ $\",\" 5\",\"end\"]}]}","format.comments.1.spec.ts":"{\"suiteName\":\"Verify comment\",\"fileName\":\"format.comments.1.spec.ts\",\"tests\":[{\"name\":\"all flavors of comments\",\"code\":[\"a = 42 ; comment OK\",\" ;; comment bad, now fixed \",\"; TODO: something super crazy \",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"limit formatting for routine comments\",\"code\":[\";+\",\"; My procedure\",\";\",\";; Preserve spacing in routine docs\",\" ; fix left alignment though\",\"; And trim the right side of the comment blocks \",\"; :Args:\",\"; var1: in, required, unknown\",\"; My favorite thing\",\"; :Keywords:\",\"; kw1: in, optional, type=boolean\",\"; Super Cool flag\",\";\",\";-\",\"pro mypro, var1, var2, KW1=kw1, KW2=kw2\",\" compile_opt idl2\",\" if !true then begin\",\" print, 'yes'\",\" endif\",\"end\"]},{\"name\":\"add placeholder case for variable docs\",\"code\":[\" compile_opt idl2\",\"\",\" ;+ comment for variable\",\" ; leave indent formatting alone for now\",\" ;- stopped here\",\" a = 'something'\",\"end\"]},{\"name\":\" do not trim string before comment after line continuation\",\"code\":[\"compile_opt idl2\",\" ; left align\",\" a = 5 ; trim\",\"MESSAGE, $ ; keep my space!\",\"'baaaad'\",\"end\",\"\"]}]}","format.executive-commands.1.spec.ts":"{\"suiteName\":\"Executive command formatting\",\"fileName\":\"format.executive-commands.1.spec.ts\",\"tests\":[{\"name\":\"works without main end\",\"code\":[\"compile_opt idl2\",\"\",\".run something\",\" .compile myfile.pro \",\" .reset \",\"\"]}]}","format.line-separators.1.spec.ts":"{\"suiteName\":\"Line separator formatting\",\"fileName\":\"format.line-separators.1.spec.ts\",\"tests\":[{\"name\":\"always remove line separators, never allow them\",\"code\":[\"\",\"\",\"compile_opt idl2\",\"\",\"if !true then begin & a = b & b = c & c = d & endif\",\"\",\"end\",\"\"]}]}","format.line-separators.2.spec.ts":"{\"suiteName\":\"Line separators (&)\",\"fileName\":\"format.line-separators.2.spec.ts\",\"tests\":[{\"name\":\"Another example from docs\",\"code\":[\"compile_opt idl2\",\"\",\"if rtol lt ftol then begin ;Done?\",\"t = y[0] & y[0] = y[ilo] & y[ilo] = t ;Sort so fcn min is 0th elem\",\"t = p[*,ilo] & p[*,ilo] = p[*,0] & p[*,0] = t\",\"return, t ;params for fcn min\",\"endif\",\"\",\"end\"]}]}","format.new-lines.1.spec.ts":"{\"suiteName\":\"Verify new lines\",\"fileName\":\"format.new-lines.1.spec.ts\",\"tests\":[{\"name\":\"cannot have more than one empty line\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"\",\"\",\"return\",\"\",\"\",\"end\"]}]}","format.python.1.spec.ts":"{\"suiteName\":\"Format python code\",\"fileName\":\"format.python.1.spec.ts\",\"tests\":[{\"name\":\"for consistent spacing\",\"code\":[\"compile_opt idl2\",\"\",\">>>from idlpy import *\",\">>> arr = IDL.randomu(None, 10000)\",\">>> spec = IDL.fft_powerspectrum(arr, 0.1)\",\"end\",\"\"]}]}","format.respect-errors.1.spec.ts":"{\"suiteName\":\"Verify we do not format when we have bad syntax errors\",\"fileName\":\"format.respect-errors.1.spec.ts\",\"tests\":[{\"name\":\"unclosed tokens are ignored\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3 \",\" compile_opt idl2 \",\" \",\" a = myfunc(\",\"end \"]},{\"name\":\"unclosed main level is ignored\",\"code\":[\" compile_opt idl2 \",\" \",\"a = 5 \"]}]}","format.routines.1.spec.ts":"{\"suiteName\":\"Verify we format routines\",\"fileName\":\"format.routines.1.spec.ts\",\"tests\":[{\"name\":\"formats basic routine\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"\",\"end\"]},{\"name\":\"formats basic method\",\"code\":[\"function myclass::mymethod, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3\",\" compile_opt idl2\",\"return, 1\",\"\",\"end\"]}]}","format.snap.1.spec.ts":"{\"suiteName\":\"Verify snapping branches to remove leading and trailing spaces\",\"fileName\":\"format.snap.1.spec.ts\",\"tests\":[{\"name\":\"all snap cases\",\"code\":[\"function test, a, $\",\" b\",\"\",\" compile_opt idl2\",\"\",\" wait, 0.5\",\"\",\" return, 1\",\"end\",\"\",\"function test::class, a, $\",\" b\",\"\",\" compile_opt idl2\",\"\",\" wait, 0.5\",\"\",\" return, 1\",\"end\",\"\",\"pro test::class, a, $\",\" b\",\"\",\" compile_opt idl2\",\"\",\" wait, 0.5\",\"\",\"end\",\"\",\"pro test, a, $\",\" b\",\"\",\" compile_opt idl2\",\"\",\" wait, 0.5\",\"\",\" if !true then begin\",\"\",\" print, 5\",\"\",\" print, 6\",\" \",\" endif\",\"\",\" switch (!true) of\",\"\",\" (42 eq 42): begin\",\"\",\" end\",\"\",\" else: begin\",\"\",\" ; do nothing\",\"\",\" end\",\"\",\" endswitch\",\"\",\"end\",\"\",\"\",\"compile_opt idl2\",\"\",\"print, 5\",\"\",\"wait, 2\",\"\",\"test\",\"\",\"print, 'Finished'\",\"\",\"end\"]}]}","format.trimming.1.spec.ts":"{\"suiteName\":\"Verify trimming lines\",\"fileName\":\"format.trimming.1.spec.ts\",\"tests\":[{\"name\":\"all lines should be trimmed from the right\",\"code\":[\"pro mypro, arg1, arg2, arg3, KW1=kw1,$ ; commment\",\"KW2 = kw2, KW3 = kw3 \",\" compile_opt idl2 \",\" \",\"end \"]}]}","style.control.spec.ts":"{\"suiteName\":\"Control statement styling\",\"fileName\":\"style.control.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" continue\",\" break\",\" forward_function\",\" common block, var1, var2, etc\",\" goto, myjump\",\" myjump:\",\"end\",\"\",\"function myfuncfunc\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\"compile_opt idl2\",\"\",\"; for loop\",\"for i=0,100,3 do begin\",\"\",\"endfor\",\"\",\"; foreach loop\",\"foreach val, var, key, do begin\",\"\",\"endforeach\",\"\",\"; while loop\",\"while !true do begin\",\"\",\"endwhile\",\"\",\"; repeat loop\",\"repeat print, !true until !false\",\"\",\"; switch statement\",\"switch !true of\",\" else: ; something\",\"endswitch\",\"\",\"; case statement\",\"case !true of\",\" else: ; something\",\"endcase\",\"\",\"; if statement\",\"if !true then begin\",\"\",\"endif else begin\",\"\",\"endelse\",\"\",\"; structure inheritance\",\"mystruct = {myname, INHerits plot}\",\"\",\"; executive command\",\".reset\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"control\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" continue\",\" break\",\" forward_function\",\" common block, var1, var2, etc\",\" goto, myjump\",\" myjump:\",\"end\",\"\",\"function myfuncfunc\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\"compile_opt idl2\",\"\",\"; for loop\",\"for i=0,100,3 do begin\",\"\",\"endfor\",\"\",\"; foreach loop\",\"foreach val, var, key, do begin\",\"\",\"endforeach\",\"\",\"; while loop\",\"while !true do begin\",\"\",\"endwhile\",\"\",\"; repeat loop\",\"repeat print, !true until !false\",\"\",\"; switch statement\",\"switch !true of\",\" else: ; something\",\"endswitch\",\"\",\"; case statement\",\"case !true of\",\" else: ; something\",\"endcase\",\"\",\"; if statement\",\"if !true then begin\",\"\",\"endif else begin\",\"\",\"endelse\",\"\",\"; structure inheritance\",\"mystruct = {myname, INHerits plot}\",\"\",\"; executive command\",\".reset\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"control\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" continue\",\" break\",\" forward_function\",\" common block, var1, var2, etc\",\" goto, myjump\",\" myjump:\",\"end\",\"\",\"function myfuncfunc\",\" compile_opt idl2\",\" return, 1\",\"end\",\"\",\"compile_opt idl2\",\"\",\"; for loop\",\"for i=0,100,3 do begin\",\"\",\"endfor\",\"\",\"; foreach loop\",\"foreach val, var, key, do begin\",\"\",\"endforeach\",\"\",\"; while loop\",\"while !true do begin\",\"\",\"endwhile\",\"\",\"; repeat loop\",\"repeat print, !true until !false\",\"\",\"; switch statement\",\"switch !true of\",\" else: ; something\",\"endswitch\",\"\",\"; case statement\",\"case !true of\",\" else: ; something\",\"endcase\",\"\",\"; if statement\",\"if !true then begin\",\"\",\"endif else begin\",\"\",\"endelse\",\"\",\"; structure inheritance\",\"mystruct = {myname, INHerits plot}\",\"\",\"; executive command\",\".reset\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"control\":\"none\"}}}]}","style.internal-routines.spec.ts":"{\"suiteName\":\"Style internal routines\",\"fileName\":\"style.internal-routines.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" Return\",\"end\",\"\",\"compile_opt idl2\",\"\",\"PRINT\",\"Openr\",\"\",\"p = PLOT()\",\"\",\"r = enviraster()\",\"\",\"o = idlneturl()\",\"\",\"s = IDLFFSHAPE()\",\"\",\"!null = STRTOK('something')\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"match\"}}},{\"name\":\"using no format\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\" Return\",\"end\",\"\",\"compile_opt idl2\",\"\",\"PRINT\",\"Openr\",\"\",\"p = PLOT()\",\"\",\"r = enviraster()\",\"\",\"o = idlneturl()\",\"\",\"s = IDLFFSHAPE()\",\"\",\"!null = STRTOK('something')\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"none\"}}}]}","style.user-routines.spec.ts":"{\"suiteName\":\"Style user routines\",\"fileName\":\"style.user-routines.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"pro test_things\",\" compile_opt idl2\",\"end\",\"\",\"function test_THINGS\",\" compile_opt idl2\",\" return, 42\",\"end\",\"\",\"compile_opt idl2\",\"\",\"TEST_THINGS\",\"!null = test_things()\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"match\"}}},{\"name\":\"using no format\",\"code\":[\"pro test_things\",\" compile_opt idl2\",\"end\",\"\",\"function test_THINGS\",\" compile_opt idl2\",\" return, 42\",\"end\",\"\",\"compile_opt idl2\",\"\",\"TEST_THINGS\",\"!null = test_things()\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"none\"}}}]}","style.keywords.1.spec.ts":"{\"suiteName\":\"Verify keywords\",\"fileName\":\"style.keywords.1.spec.ts\",\"tests\":[{\"name\":\"basic formatting\",\"code\":[\"compile_opt idl2\",\"\",\"a = myfunc(KW1=kw2, /KW3)\",\"end\"]},{\"name\":\"with line continuation\",\"code\":[\"compile_opt idl2\",\"\",\"Graphic, name, arg1, arg2, $\",\"/AUTO_CROSSHAIR, COLOR=color, LINESTYLE=linestyle, $\",\"SYMBOL=SYMBOL, THICK=thick, LAYOUT=layout, TEST=test, _EXTRA=ex, $\",\"GRAPHIC=graphic\",\"\",\"end\"]},{\"name\":\"solo keyword\",\"code\":[\"compile_opt idl2\",\"\",\"a = myfunc(KW1=kw2)\",\"end\"]},{\"name\":\"solo binary keyword\",\"code\":[\"compile_opt idl2\",\"\",\"a = myfunc(/KW2)\",\"end\"]},{\"name\":\"preserve other children after keyword when we format\",\"code\":[\"compile_opt idl2\",\"tvcrs,x,y,/dev $ ;Restore cursor\",\" kw=2\",\"\",\"end\"]}]}","style.methods.spec.ts":"{\"suiteName\":\"Method styling\",\"fileName\":\"style.methods.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\" compile_opt idl2\",\"\",\"a = myclass . mymethod()\",\"myclass . mymethod\",\"a = myclass -> mymethod()\",\"myclass -> mymethod\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"methods\":\"dot\"}}},{\"name\":\"using dated format\",\"code\":[\" compile_opt idl2\",\"\",\"a = myclass . mymethod()\",\"myclass . mymethod\",\"a = myclass -> mymethod()\",\"myclass -> mymethod\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"methods\":\"arrow\"}}},{\"name\":\"using no format\",\"code\":[\" compile_opt idl2\",\"\",\"a = myclass . mymethod()\",\"myclass . mymethod\",\"a = myclass -> mymethod()\",\"myclass -> mymethod\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"methods\":\"none\"}}}]}","style.methods-call.spec.ts":"{\"suiteName\":\"Method styling\",\"fileName\":\"style.methods-call.spec.ts\",\"tests\":[{\"name\":\"match\",\"code\":[\"function myclass::MYMETHOD\",\"compile_opt idl2\",\"\",\"!null = self.myMethod()\",\"\",\"return, 1\",\"end\",\"\",\"pro myclass::MYMETHOD\",\"compile_opt idl2\",\"\",\"self.myMethod\",\"end\",\"\",\"pro auto_doc_example\",\"compile_opt idl2\",\"\",\"p = IDLgrSurface()\",\"!null = p.getFullIdentifier()\",\"p.SETVERTEXATTRIBUTEDATA\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"match\"}}},{\"name\":\"none\",\"code\":[\"function myclass::MYMETHOD\",\"compile_opt idl2\",\"\",\"!null = self.myMethod()\",\"\",\"return, 1\",\"end\",\"\",\"pro myclass::MYMETHOD\",\"compile_opt idl2\",\"\",\"self.myMethod\",\"end\",\"\",\"pro auto_doc_example\",\"compile_opt idl2\",\"\",\"p = IDLgrSurface()\",\"!null = p.getFullIdentifier()\",\"p.SETVERTEXATTRIBUTEDATA\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"routines\":\"none\"}}}]}","style.prompts.spec.ts":"{\"suiteName\":\"Prompt styling\",\"fileName\":\"style.prompts.spec.ts\",\"tests\":[{\"name\":\"format ENVI and IDL\",\"code\":[\"\",\"\",\"compile_opt idl2\",\"\",\"idl> print, 17\",\"\",\" envi>a = 5 + 6\",\"\",\"end\",\"\"]}]}","style.numbers.spec.ts":"{\"suiteName\":\"Number styling\",\"fileName\":\"style.numbers.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 45Ll\",\"\",\"a = \\\"101010\\\"bll\",\"\",\"a = \\\"777\\\"oS\",\"\",\"a = \\\"fFf\\\"xlL\",\"\",\"a = '101010'bll\",\"\",\"a = '777'oS\",\"\",\"a = 'fFf'xlL\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"numbers\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 45Ll\",\"\",\"a = \\\"101010\\\"bll\",\"\",\"a = \\\"777\\\"oS\",\"\",\"a = \\\"fFf\\\"xlL\",\"\",\"a = '101010'bll\",\"\",\"a = '777'oS\",\"\",\"a = 'fFf'xlL\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"numbers\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 45Ll\",\"\",\"a = \\\"101010\\\"bll\",\"\",\"a = \\\"777\\\"oS\",\"\",\"a = \\\"fFf\\\"xlL\",\"\",\"a = '101010'bll\",\"\",\"a = '777'oS\",\"\",\"a = 'fFf'xlL\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"numbers\":\"none\"}}}]}","style.hex.spec.ts":"{\"suiteName\":\"Hex number styling\",\"fileName\":\"style.hex.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0XaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"hex\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0XaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"hex\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0XaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"hex\":\"none\"}}}]}","style.octal.spec.ts":"{\"suiteName\":\"Octal number styling\",\"fileName\":\"style.octal.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0OaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"octal\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0OaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"octal\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0OaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"octal\":\"none\"}}}]}","style.binary.spec.ts":"{\"suiteName\":\"Binary number styling\",\"fileName\":\"style.binary.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0BaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"binary\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0BaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"binary\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = 0BaEf\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"binary\":\"none\"}}}]}","style.properties.spec.ts":"{\"suiteName\":\"Property styling\",\"fileName\":\"style.properties.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = myvar.myPROP\",\"b = {SomeThing:'cool'}\",\"!null = b.SomeThing\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"properties\":\"match\"}}},{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = myvar.myPROP\",\"b = {SomeThing:'cool'}\",\"!null = b.SomeThing\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"properties\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = myvar.myPROP\",\"b = {SomeThing:'cool'}\",\"!null = b.SomeThing\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"properties\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = myvar.myPROP\",\"b = {SomeThing:'cool'}\",\"!null = b.SomeThing\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"properties\":\"none\"}}}]}","style.variables.1.spec.ts":"{\"suiteName\":\"Verify variable styling\",\"fileName\":\"style.variables.1.spec.ts\",\"tests\":[{\"name\":\"in procedures with modern formatting\",\"code\":[\"pro test_things, a, someTHING, c, KW1 = kw11\",\" compile_opt idl2\",\" A = something + C + keyword_set(KW11)\",\" taSK = ENVITask('Something')\",\" TASK = !null\",\" !null = enVi.openRaster()\",\" !null = enviTask.parameter()\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"match\"}}},{\"name\":\"in procedures with no formatting\",\"code\":[\"pro test_things, a, someTHING, c, KW1 = kw11\",\" compile_opt idl2\",\" A = something + C + keyword_set(KW11)\",\" taSK = ENVITask('Something')\",\" TASK = !null\",\" !null = enVi.openRaster()\",\" !null = enviTask.parameter()\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"none\"}}},{\"name\":\"in functions with modern formatting\",\"code\":[\"function test_things, a, someTHING, c, KW1 = kw11\",\" compile_opt idl2\",\" A = something + C + keyword_set(KW11)\",\" taSK = ENVITask('Something')\",\" TASK = !null\",\" !null = enVi.openRaster()\",\" !null = enviTask.parameter()\",\" return, task\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"match\"}}},{\"name\":\"in functions with no formatting\",\"code\":[\"function test_things, a, someTHING, c, KW1 = kw11\",\" compile_opt idl2\",\" A = something + C + keyword_set(KW11)\",\" taSK = ENVITask('Something')\",\" TASK = !null\",\" !null = enVi.openRaster()\",\" !null = enviTask.parameter()\",\" return, task\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"none\"}}},{\"name\":\"in main level with modern formatting\",\"code\":[\"compile_opt idl2\",\"A = something + C + keyword_set(KW11)\",\"taSK = ENVITask('Something')\",\"TASK = !null\",\"!null = enVi.openRaster()\",\"!null = enviTask.parameter()\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"match\"}}},{\"name\":\"in main level with no formatting\",\"code\":[\"compile_opt idl2\",\"A = something + C + keyword_set(KW11)\",\"taSK = ENVITask('Something')\",\"TASK = !null\",\"!null = enVi.openRaster()\",\"!null = enviTask.parameter()\",\"end\"],\"config\":{\"style\":{\"localVariables\":\"none\"}}}]}","style.system-variables.spec.ts":"{\"suiteName\":\"System variable styling\",\"fileName\":\"style.system-variables.spec.ts\",\"tests\":[{\"name\":\"using modern format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = !SYSTEM_variable\",\"\",\"b = {!CPu, hw_vector: 0l, vector_enable: 0l, hw_ncpu: 0l,$\",\" tpool_nthreads: 0l, tpool_min_elts: 0l, tpool_max_elts: 0l}\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"systemVariables\":\"lower\"}}},{\"name\":\"using dated format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = !SYSTEM_variable\",\"\",\"b = {!CPu, hw_vector: 0l, vector_enable: 0l, hw_ncpu: 0l,$\",\" tpool_nthreads: 0l, tpool_min_elts: 0l, tpool_max_elts: 0l}\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"systemVariables\":\"upper\"}}},{\"name\":\"using no format\",\"code\":[\"compile_opt idl2, hidden\",\"\",\"a = !SYSTEM_variable\",\"\",\"b = {!CPu, hw_vector: 0l, vector_enable: 0l, hw_ncpu: 0l,$\",\" tpool_nthreads: 0l, tpool_min_elts: 0l, tpool_max_elts: 0l}\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"systemVariables\":\"none\"}}}]}","format.indent.1.spec.ts":"{\"suiteName\":\"Verify adjusting indent adjusts spacing\",\"fileName\":\"format.indent.1.spec.ts\",\"tests\":[{\"name\":\"set indent to 3\",\"code\":[\"pro mypro\",\" compile_opt idl2\",\"\",\" ; double quote\",\" a = \\\"something\\\"\",\"\",\" ; double quote with single quote\",\" a = \\\"'\\\"\",\"\",\" ; escaped double quote\",\" a = \\\"escaped\\\"\\\"formatting\\\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"tabWidth\":3,\"style\":{\"quotes\":\"single\"}}}]}","lib-examples.1.spec.ts":"{\"suiteName\":\"Verify code snippets from the lib folder\",\"fileName\":\"lib-examples.1.spec.ts\",\"tests\":[{\"name\":\"cw_ogc_wcs_cap.pro 1\",\"code\":[\"compile_opt idl2\",\"subsel = make_array(2, numRows, /byte) ; an array to hold the unique values\",\"subsel[0,0] = sel[*,1]\",\"lastRow = sel[1,0]\",\"ri = 1\",\"\",\";filter out all the rows that repeat\",\"for i=1, cnt-1 do begin\",\" if (lastRow ne sel[1,i]) then begin\",\" sel[0,i] = 1\",\" subsel[*,ri] = sel[*,i]\",\" lastRow = sel[1,i]\",\" ri++\",\" endif\",\"endfor\",\"\",\"end\"]},{\"name\":\"cw_ogc_wcs_cap.pro 2\",\"code\":[\"\",\"if ((*pstate).mouseState eq 1) then begin\",\"\",\" if (totCOBs gt rows) then begin\",\" if ((*pstate).scrollUp eq 0) then begin ; scroll down\",\" if ((*pstate).cobIndex lt totCOBs) then begin\",\"\",\"\",\" (*pstate).cobIndex = (*pstate).cobIndex + (*pstate).pageScrlInc\",\"\",\" idx = (*pstate).cobIndex\",\" skip = idx-rows\",\" if (skip gt (totCOBs - rows)) then begin\",\" skip = totCOBs - rows\",\" ;(*pstate).cobIndex = totCOBs-rows\",\" (*pstate).cobIndex = totCOBs\",\" endif\",\"\",\" res = (*pstate).owcs->GetCoverageOfferingBriefs(index=skip, number=rows)\",\" cw_ogc_wcs_cap_display_cap_table, ev, res\",\"\",\" endif\",\" endif else begin ; scroll up\",\" if ((*pstate).cobIndex gt rows) then begin\",\"\",\"\",\" (*pstate).cobIndex = (*pstate).cobIndex - (*pstate).pageScrlInc\",\"\",\" idx = (*pstate).cobIndex\",\" skip = idx-rows\",\"\",\" if (skip lt 0) then begin\",\" skip = 0\",\" (*pstate).cobIndex = rows\",\" endif\",\"\",\" res = (*pstate).owcs->GetCoverageOfferingBriefs(index=skip, number=rows)\",\" cw_ogc_wcs_cap_display_cap_table, ev, res\",\"\",\" endif\",\" endelse\",\" endif\",\"endif\",\"\",\"end\"]}]}","lib-examples.2.spec.ts":"{\"suiteName\":\"Lib examples 2\",\"fileName\":\"lib-examples.2.spec.ts\",\"tests\":[{\"name\":\"dist.pro\",\"code\":[\"function dist,n,m ;Return a rectangular array in which each pixel = euclidian\",\" ;distance from the origin.\",\"compile_opt idl2\",\"\",\"on_error,2 ;Return to caller if an error occurs\",\"\",\"n1 = n[0]\",\"m1 = (n_elements(m) le 0) ? n1 : m[0]\",\"x=findgen(n1) ;Make a row\",\"x = (x < (n1-x)) ^ 2 ;column squares\",\"\",\"a = FLTARR(n1,m1,/NOZERO) ;Make array\",\"\",\"for i=0L, m1/2 do begin ;Row loop\",\" y = sqrt(x + i^2.) ;Euclidian distance\",\" a[0,i] = y ;Insert the row\",\" if i ne 0 then a[0, m1-i] = y ;Symmetrical\",\"endfor\",\"return,a\",\"end\"]}]}","style.logic-case.1.spec.ts":"{\"suiteName\":\"Verify we style case\",\"fileName\":\"style.logic-case.1.spec.ts\",\"tests\":[{\"name\":\"formats messy case\",\"code\":[\"CASE x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\" 2 $\",\" : $\",\" PRINT, 'one' + func()\",\" ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDCASE\",\"end\"]},{\"name\":\"formats nested case\",\"code\":[\"CASE x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" CASE x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDCASE\",\"END\",\"ENDCASE\",\"end\"]},{\"name\":\"Properly format indents for case without line continuation\",\"code\":[\"compile_opt idl2\",\" ; determine how to proceed\",\" case !true of\",\" ; only have positive values\",\" negative eq !null: begin\",\" ranges[*, i] = [0, positive]\",\" end\",\"\",\" ; only have negative values\",\" positive eq !null: begin\",\" ranges[*, i] = [-negative, 0]\",\" end\",\"\",\" ; have positive and negative values\",\" else: begin\",\" ; get our bounds\",\" maxVal = negative > positive\",\"\",\" ; populate range\",\" ranges[*, i] = [-maxVal, maxVal]\",\" end\",\" endcase\",\"end\"]},{\"name\":\"removes spaces in logical default\",\"code\":[\"compile_opt idl2\",\"case N_PARAMS() of\",\"else : ; remove my space to the left after \\\"else\\\"\",\"endcase\",\"end\"]},{\"name\":\"properly formats this case/switch style\",\"code\":[\"compile_opt idl2\",\"\",\"; Just determine what to do and register.\",\"case 1 of\",\"\",\" keyword_set(visualization): $\",\" oSystem->RegisterVisualization, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(annotation): $\",\" oSystem->RegisterAnnotation, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(user_interface): $\",\"oSystem->RegisterUserInterface, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(ui_panel): $\",\"oSystem->RegisterUIPanel, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(ui_service): $\",\"oSystem->RegisterUIService, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(file_reader): $\",\"oSystem->RegisterFileReader, strName, strClassName, _EXTRA = _extra\",\"\",\"keyword_set(file_writer): $\",\"oSystem->RegisterFileWriter, strName, strClassName, _EXTRA = _extra\",\"\",\"else: $\",\"oSystem->RegisterTool, strName, strClassName, _EXTRA = _extra\",\"\",\"endcase\",\"end\"]}]}","style.logic-if-then.1.spec.ts":"{\"suiteName\":\"Verify we style if-then\",\"fileName\":\"style.logic-if-then.1.spec.ts\",\"tests\":[{\"name\":\"complex scenarios for if-then-else\",\"code\":[\" COMPILE_OPT idl2\",\"\",\" IF (n_elements(useDicomexIn) EQ 1) THEN $\",\" useDicomex = keyword_set(useDicomexIn) $\",\" ELSE $\",\" useDicomex = 1\",\"\",\" if !true then print, 'true' else print, 'false'\",\"\",\" IF (n_elements(useDicomexIn) EQ 1) $\",\"THEN $\",\" useDicomex = keyword_set(useDicomexIn) $\",\" ELSE $\",\" useDicomex = 1\",\"\",\" if !true then begin\",\"print, 'no'\",\" endif else begin\",\" b = 42\",\" endelse\",\"\",\"end\"]},{\"name\":\"keep on indenting with line continuations\",\"code\":[\"compile_opt idl2\",\"; when in paren, not as pretty\",\"if (!true $\",\" ) then $\",\"imageFFT = FFT(image, -1)\",\"\",\";;outside of paren, looks much nicer as long as enclosed\",\"if (!true)$\",\" then $\",\"imageFFT = FFT(image, -1)\",\"\",\"a = 5\",\"end\"]},{\"name\":\"complex indentation for if statement\",\"code\":[\"compile_opt idl2\",\"if ((imageSz.N_DIMENSIONS ne 2) || $\",\"((imageSz.TYPE ne 6) && (imageSz.TYPE ne 9)) || $\",\" MAX(imageSz.DIMENSIONS[0 : 1] ne imageDims[0] * 2)) then begin\",\" ; Double the image size and pad with zeros\",\" bigImage = dblarr(imageDims[0] * 2, imageDims[1] * 2)\",\" bigImage[0 : imageDims[0] - 1, 0 : imageDims[1] - 1] = image\",\" imageFFT = FFT(bigImage, -1)\",\" imageNElts = N_ELEMENTS(bigImage)\",\" endif\",\"end\"]},{\"name\":\"very complex if statement for regression test\",\"code\":[\"compile_opt idl2\",\"\",\" ;; Check to see if texture map was passed in as 3 or 4 separate 2D\",\" ;; arrays. textureRed, textureGreen, and textureBlue must all\",\" ;; be 2D arrays of the same size and type and textureImage must\",\" ;; not be set.\",\" IF keyword_set(textureRed) && keyword_set(textureGreen) && $\",\" keyword_set(textureBlue) && ~keyword_set(textureImage) && $\",\" (size(reform(textureRed),/n_dimensions) EQ 2) && $\",\" (size(reform(textureGreen),/n_dimensions) EQ 2) && $\",\" (size(reform(textureBlue),/n_dimensions) EQ 2) && $\",\" ( ((textmap_x=(size(reform(textureRed),/dimensions))[0])) EQ $\",\" (size(reform(textureGreen),/dimensions))[0] ) && $\",\" ( textmap_x EQ (size(reform(textureBlue),/dimensions))[0] ) && $\",\" ( ((textmap_y=(size(reform(textureRed),/dimensions))[1])) EQ $\",\" (size(reform(textureGreen),/dimensions))[1] ) && $\",\" ( textmap_y EQ (size(reform(textureBlue),/dimensions))[1] ) && $\",\" ( ((textmap_type=(size(reform(textureRed),/type))[0])) EQ $\",\" (size(reform(textureGreen),/type))[0] ) && $\",\" ( textmap_type EQ (size(reform(textureBlue),/type))[0] ) && $\",\" ( where(textmap_type EQ [0l,6,7,8,9,10,11]) EQ -1 ) THEN BEGIN\",\" ;; textureAlpha, if set, must match TEXTURE_* in size and type\",\" IF keyword_set(textureAlpha) && $\",\" (size(reform(textureAlpha),/n_dimensions) EQ 2) && $\",\" ( textmap_x EQ (size(reform(textureAlpha),/dimensions))[0]) && $\",\" ( textmap_y EQ (size(reform(textureAlpha),/dimensions))[1]) && $\",\" ( textmap_type EQ (size(reform(textureAlpha),/type))[0]) $\",\" THEN BEGIN\",\" textData = make_array(4,textmap_x,textmap_y,type=textmap_type)\",\" textData[0,*,*] = textureRed\",\" textData[1,*,*] = textureGreen\",\" textData[2,*,*] = textureBlue\",\" textData[3,*,*] = textureAlpha\",\" ENDIF ELSE BEGIN\",\" textData = make_array(3,textmap_x,textmap_y,type=textmap_type)\",\" textData[0,*,*] = textureRed\",\" textData[1,*,*] = textureGreen\",\" textData[2,*,*] = textureBlue\",\" ENDELSE\",\" oTextMap = obj_new('idlitDataIDLArray3d', textData, $\",\" NAME='TEXTURE')\",\" oParmSet->add, oTextMap, PARAMETER_NAME= \\\"TEXTURE\\\"\",\" ENDIF\",\"\",\"end\"]}]}","style.logic-switch.1.spec.ts":"{\"suiteName\":\"Verify we style switch\",\"fileName\":\"style.logic-switch.1.spec.ts\",\"tests\":[{\"name\":\"formats messy switch\",\"code\":[\"SWITCH x OF\",\" ; something cool\",\"1 $\",\" : $\",\" PRINT, 'one' + func()\",\" 2 $\",\" : $\",\" PRINT, 'one' + func()\",\" ELSE: BEGIN\",\" dat = {myStruct}\",\" PRINT, 'Please enter a value between 1 and 4'\",\" END\",\"ENDCASE\",\"end\"]},{\"name\":\"formats nested switch\",\"code\":[\"SWITCH x OF\",\"1: PRINT, 'one'\",\"ELSE: BEGIN\",\" switch x OF\",\" 2: PRINT, 'two'\",\" ELSE: BEGIN\",\" END\",\" ENDCASE\",\"END\",\"ENDCASE\",\"end\"]}]}","style.logic-ternary.1.spec.ts":"{\"suiteName\":\"Verify we style ternary operators well\",\"fileName\":\"style.logic-ternary.1.spec.ts\",\"tests\":[{\"name\":\"simple case with spacing\",\"code\":[\"nPrint = (nTiles lt 100) ? 1:ceil(nTiles / 100.0)\"]},{\"name\":\"Case to preserve spacing before else\",\"code\":[\"oWorld = OBJ_VALID(oLayer) ? oLayer->GetWorld(): OBJ_NEW()\"]}]}","style.methods.1.spec.ts":"{\"suiteName\":\"Verify style for methods\",\"fileName\":\"style.methods.1.spec.ts\",\"tests\":[{\"name\":\"remove excess spaces\",\"code\":[\" compile_opt idl2\",\"\",\"a = myclass . mymethod()\",\"myclass . mymethod\",\"a = myclass -> mymethod()\",\"myclass -> mymethod\",\"\",\"end\"]}]}","style.operators.1.spec.ts":"{\"suiteName\":\"Verify operators\",\"fileName\":\"style.operators.1.spec.ts\",\"tests\":[{\"name\":\"pointers\",\"code\":[\"compile_opt idl2\",\"\",\"; complex pointers\",\"(*pstate).coDesCovIdArr[(*pstate).coDesCovIdArrIdx++] = ogc_wcs_descov(ev.top, (*pstate).owcs, covNames, '')\",\"\",\"end\"]},{\"name\":\"pointers\",\"code\":[\"compile_opt idl2\",\"\",\"*ptr = 42\",\"end\"]},{\"name\":\"operators that should not have spaces\",\"code\":[\"compile_opt idl2\",\"\",\"a++\",\"b--\",\"++c\",\"--d\",\"a += 6\",\"y -= 42\",\"m = --6\",\"n = ++4\",\"end\"]},{\"name\":\"handle tilde\",\"code\":[\"if ~keyword_set(difference_raster_uri) then difference_raster_uri = e.GetTemporaryFilename()\"]},{\"name\":\"pointer dereference and multiplication\",\"code\":[\"compile_opt idl2\",\"a = 5*10\",\"(*ptr).prop = 5\",\"b = *ptr\",\"segsUpper.Add, * overlaps.LOWER[mapXY[0], mapXY[1] - 1], /EXTRACT\",\"end\"]},{\"name\":\"remove spaces before operators where we do not need then\",\"code\":[\" compile_opt idl2\",\"\",\" a = - 1\",\" mypro, - 1\",\"\",\" ; create a struture to store information about our tile overlaps\",\" overlaps = { $\",\" IDX_X: - 0l $\",\" }\",\"deltas = ranges[1, *]-ranges[0, *]\",\"idxMin = [0 : - 2]\",\"end\"]},{\"name\":\"preserve spacing here\",\"code\":[\"a = ['Anomaly Detection: ' + task.MEAN_CALCULATION_METHOD]\"]},{\"name\":\"preserve spacing here too\",\"code\":[\"cs = !dpi *[0d : num_period - 1]\"]},{\"name\":\"operators by paren get properly ignored for trimming\",\"code\":[\"compile_opt idl2\",\" if (and filtMask and igMask) then filters = 'Image Files'\",\" if (eq filtMask and igMask) then filters = 'Image Files'\",\" if (ge filtMask and igMask) then filters = 'Image Files'\",\" if (gt filtMask and igMask) then filters = 'Image Files'\",\" if (le filtMask and igMask) then filters = 'Image Files'\",\" if (lt filtMask and igMask) then filters = 'Image Files'\",\" if (mod filtMask and igMask) then filters = 'Image Files'\",\" if (ne filtMask and igMask) then filters = 'Image Files'\",\" if (not filtMask and igMask) then filters = 'Image Files'\",\" if (or filtMask and igMask) then filters = 'Image Files'\",\" if (xor filtMask and igMask) then filters = 'Image Files'\",\"end\"]}]}","style.quotes-double.1.spec.ts":"{\"suiteName\":\"Verify double quote styling\",\"fileName\":\"style.quotes-double.1.spec.ts\",\"tests\":[{\"name\":\"convert double to single quote\",\"code\":[\" compile_opt idl2\",\"\",\" ; double quote\",\" a = \\\"something\\\"\",\"\",\" ; double quote with single quote\",\" a = \\\"'\\\"\",\"\",\" ; escaped double quote\",\" a = \\\"escaped\\\"\\\"formatting\\\"\",\"\",\" ; number strings\",\" a = \\\"010101\\\"b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"single\"}}},{\"name\":\"keep formatting when double quotes is preference\",\"code\":[\" compile_opt idl2\",\"\",\" ; double quote\",\" a = \\\"something\\\"\",\"\",\" ; double quote with single quote\",\" a = '\\\"'\",\"\",\" ; escaped double quote\",\" a = \\\"escaped\\\"\\\"formatting\\\"\",\"\",\" ; number strings\",\" a = \\\"010101\\\"b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"double\"}}}]}","style.quotes-none.1.spec.ts":"{\"suiteName\":\"Verify no formatting of quotes\",\"fileName\":\"style.quotes-none.1.spec.ts\",\"tests\":[{\"name\":\"preserve all quotes\",\"code\":[\"compile_opt idl2\",\"\",\"message, 'Each dimension must be greater than 1.\\\"'\",\"\",\"a = \\\"5\\\"\",\"\",\"a = 'fourty two'\",\"\",\"; for chris and doug\",\"a = '1'\",\"\",\"\",\" ; number strings\",\" a = \\\"010101\\\"b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"none\"}}}]}","style.quotes-nested.1.spec.ts":"{\"suiteName\":\"Verify double quote parsing\",\"fileName\":\"style.quotes-nested.1.spec.ts\",\"tests\":[{\"name\":\"preserve nested double quote when we use single\",\"code\":[\"compile_opt idl2\",\"\",\"message, 'Each dimension must be greater than 1.\\\"'\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"single\"}}},{\"name\":\"preserve nested single quote when we use double\",\"code\":[\"compile_opt idl2\",\"\",\"message, \\\"Each dimension must be greater than 1.'\\\"\",\"\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"double\"}}}]}","style.quotes-single.1.spec.ts":"{\"suiteName\":\"Verify single quote parsing\",\"fileName\":\"style.quotes-single.1.spec.ts\",\"tests\":[{\"name\":\"convert single to double quote\",\"code\":[\" compile_opt idl2\",\"\",\" ; single quote\",\" a = 'something'\",\"\",\" ; double quote with single quote\",\" a = '\\\"'\",\"\",\" ; escaped single quote\",\" a = 'escaped''formatting'\",\"\",\" ; number strings\",\" a = '010101'b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"double\"}}},{\"name\":\"keep formatting when single quotes is preference\",\"code\":[\" compile_opt idl2\",\"\",\" ; single quote\",\" a = 'something'\",\"\",\" ; double quote with single quote\",\" a = \\\"'\\\"\",\"\",\" ; escaped single quote\",\" a = 'escaped''formatting'\",\"\",\" ; number strings\",\" a = '010101'b\",\"end\"],\"config\":{\"formatter\":\"fiddle\",\"style\":{\"quotes\":\"single\"}}}]}","style.string-literal.1.spec.ts":"{\"suiteName\":\"Verify string literal styling\",\"fileName\":\"style.string-literal.1.spec.ts\",\"tests\":[{\"name\":\"simple\",\"code\":[\" compile_opt idl2 \",\"a = `my string with${expression}`\",\"b = `something ${5 + 6*12}`\",\" c = ` preserve as string`\",\";preserve interior spacing\",\"a = `with ${expression()} else`\",\" \",\"end \"]},{\"name\":\"multi-line\",\"code\":[\"compile_opt idl2\",\"; thing\",\"a = ` first\",\" second\",\" third\",\"`\",\"end\"]}]}","style.structures.1.spec.ts":"{\"suiteName\":\"Verify structures\",\"fileName\":\"style.structures.1.spec.ts\",\"tests\":[{\"name\":\"simple\",\"code\":[\" compile_opt idl2 \",\"fourty2 = { mystruct }\",\" \",\"end \"]},{\"name\":\"structure\",\"code\":[\"pro folderwatch__define\",\" compile_opt idl2, hidden\",\" on_error, 2\",\"\",\" void = { $\",\" FOLDERWATCH, $\",\" inherits idl_object, $\",\" _folder: '', $\",\" _callback: '', $\",\" _userdata: ptr_new(), $\",\" _added: 0b, $\",\" _modified: 0b, $\",\" _removed: 0b, $\",\" _frequency: 0d, $\",\" _timerid: 0l, $\",\" _fileinfo: ptr_new(), $\",\" _recursive: 0b, $\",\" _active: 0b, $\",\" _incallback: 0b $\",\" }\",\"\",\"end\"]},{\"name\":\"structure with arrays\",\"code\":[\"pro folderwatch__define\",\" compile_opt idl2, hidden\",\" on_error, 2\",\"\",\" void = { $\",\" IDX_XY: [0l, 0l], $\",\" RIGHT_MEANS: ptrarr(mapDims) $\",\" }\",\"\",\"end\"]},{\"name\":\"structure with line continuations regression\",\"code\":[\" compile_opt idl2, hidden\",\"!null = {IDLNotebook, $\",\" _foo: 5}\",\"\",\" !null = $\",\" {IDLNotebook, $\",\" _foo: 5}\",\"\",\" !null = { $\",\" _foo: 5}\",\"\",\" !null = $\",\" { $\",\" _foo: 5}\",\"end\"]}]}","style.template-escape.spec.ts":"{\"suiteName\":\"Verify auto-fix/format of template escape characters\",\"fileName\":\"style.template-escape.spec.ts\",\"tests\":[{\"name\":\" only changes the last line with modern\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"end\"],\"config\":{\"style\":{\"hex\":\"lower\"}}},{\"name\":\" only changes the last line with dated\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"end\"],\"config\":{\"style\":{\"hex\":\"upper\"}}},{\"name\":\" only changes the last line with none\",\"code\":[\"compile_opt idl2\",\"a = `\\\\``\",\"a = `\\\\$`\",\"a = `\\\\\\\\`\",\"a = `\\\\b`\",\"a = `\\\\f`\",\"a = `\\\\n`\",\"a = `\\\\r`\",\"a = `\\\\t`\",\"a = `\\\\v`\",\"a = `\\\\x00 \\\\XaF`\",\"end\"],\"config\":{\"style\":{\"hex\":\"none\"}}}]}"},"auto-task-assembler-tests":{"envitask.keywords1.spec.ts":"{\"suiteName\":\"Verify keyword formatting for ENVITasks\",\"fileName\":\"envitask.keywords1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"input_raster\\\",\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"output_raster_uri\\\",\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"output_raster\\\",\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"INPUT_RASTER\\\",\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_RASTER_URI\\\",\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_RASTER\\\",\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"INPUT_RASTER\\\",\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"output_RASTER_uri\\\",\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_RASTER\\\",\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"none\"}}}]}","envitask.parameters1.spec.ts":"{\"suiteName\":\"Verify parameter formatting for ENVI Tasks\",\"fileName\":\"envitask.parameters1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_RASTER_URI\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_RASTER\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster \\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" output_raster_uri \\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" OUTPUT_RASTER \\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"none\"}}}]}","envitask.direction1.spec.ts":"{\"suiteName\":\"Verify direction formatting for ENVI Tasks\",\"fileName\":\"envitask.direction1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\" ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_raster_uri\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_raster\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"upper\"}}},{\"name\":\"lower case\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection \\\",\",\" \\\"description\\\": \\\" Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_RASTER_URI\\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_RASTER\\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"OUTPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"ATAnomalyDetection\\\",\",\" \\\"schema\\\": \\\"envitask_3.3\\\",\",\" \\\"base_class\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"atAnomalyDetection\\\",\",\" \\\"display_name\\\": \\\"AT Anomaly Detection\\\",\",\" \\\"description\\\": \\\"Runs an automated anomaly detection using the Anomaly Detection workflow from ENVI Desktop.\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster \\\",\",\" \\\"display_name\\\": \\\"Input Raster\\\",\",\" \\\"description\\\": \\\"The raster to run anomaly detection on.\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" output_raster_uri \\\",\",\" \\\"display_name\\\": \\\"Output Raster URI\\\",\",\" \\\"description\\\": \\\"Specify a string with the fully-qualified path and filename for OUTPUT_RASTER.\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": false,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIURI\\\",\",\" \\\"auto_extension\\\": \\\".dat\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" OUTPUT_RASTER \\\",\",\" \\\"display_name\\\": \\\"Output Raster\\\",\",\" \\\"description\\\": \\\"This is a reference to an ENVIRaster object.\\\",\",\" \\\"direction\\\": \\\"OUTPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"hidden\\\": false,\",\" \\\"type\\\": \\\"ENVIRaster\\\",\",\" \\\"uri_param\\\": \\\"OUTPUT_RASTER_URI\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"none\"}}}]}","envitask-legacy.keywords1.spec.ts":"{\"suiteName\":\"Verify keyword formatting for ENVI Task Legacy\",\"fileName\":\"envitask-legacy.keywords1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"input_raster\\\",\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"input_ecf_report_uri\\\",\",\" \\\"name\\\": \\\"input_ecf_report_uri\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"output_roi\\\",\",\" \\\"name\\\": \\\"output_roi\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"INPUT_RASTER\\\",\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"input_RASTER\\\",\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"none\"}}}]}","envitask-legacy.parameters1.spec.ts":"{\"suiteName\":\"Verify parameter formatting for ENVI Task Legacy\",\"fileName\":\"envitask-legacy.parameters1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"input_raster\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"input_ecf_report_uri\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_roi\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\" mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\" ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\" This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\" ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"output_roi \\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"none\"}}}]}","envitask-legacy.direction-and-req1.spec.ts":"{\"suiteName\":\"Verify direction formatting for ENVI Task Legacy\",\"fileName\":\"envitask-legacy.direction-and-req1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\" OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\" ENVIROI\\\",\",\" \\\"direction\\\": \\\"output\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\" ,\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"OUTPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"MLEFCReportToROI\\\",\",\" \\\"baseClass\\\": \\\"ENVITaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"mlEFCReportToROI\\\",\",\" \\\"displayName\\\": \\\"ML EFC Report to ROI\\\",\",\" \\\"description\\\": \\\"This task will convert an ENVI Feature Counting (EFC) report file to an ROI for use with the new and improved chip to points. The class anmes must start with positive or negative (case insensitive). You don't have to have both present, but you cannot have mor than two classes.\\\",\",\" \\\"version\\\": \\\"5.3\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"INPUT_RASTER\\\",\",\" \\\"displayName\\\": \\\"Training Data Source Raster\\\",\",\" \\\"dataType\\\": \\\"ENVIRASTER\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"Specify the original raster that was used to find training data.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"INPUT_EFC_REPORT_FILE\\\",\",\" \\\"displayName\\\": \\\"EFC Report File\\\",\",\" \\\"dataType\\\": \\\"ENVIURI\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"parameterType\\\": \\\"required\\\",\",\" \\\"description\\\": \\\"Specify the ENVI Feature Counting report file (must have a .txt extension).\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"OUTPUT_ROI\\\",\",\" \\\"displayName\\\": \\\"Output ROI\\\",\",\" \\\"dataType\\\": \\\"ENVIROI\\\",\",\" \\\"direction\\\": \\\"OUTPUT\\\",\",\" \\\"parameterType\\\": \\\"REQUIRED\\\",\",\" \\\"description\\\": \\\"The output ROI file that will contain the pixel locations of our training data.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"none\"}}}]}","idltask.keywords1.spec.ts":"{\"suiteName\":\"Verify keyword formatting for IDL Tasks\",\"fileName\":\"idltask.keywords1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"s3_url\\\",\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"local_file\\\",\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"S3_URL\\\",\",\" \\\"name\\\": \\\"S3_URL\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"LOCAL_FILE\\\",\",\" \\\"name\\\": \\\"LOCAL_FILE\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"keyword\\\": \\\"S3_url\\\",\",\" \\\"name\\\": \\\"S3_URL\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"keyword\\\": \\\"local_FILE\\\",\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"keywords\":\"none\"}}}]}","idltask.parameters1.spec.ts":"{\"suiteName\":\"Verify parameter formatting for IDL Tasks\",\"fileName\":\"idltask.parameters1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"S3_URL\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"LOCAL_FILE\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"S3_URL\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"properties\":\"none\"}}}]}","idltask.direction1.spec.ts":"{\"suiteName\":\"Verify direction formatting for IDL Tasks\",\"fileName\":\"idltask.direction1.spec.ts\",\"tests\":[{\"name\":\"upper case\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"upper\"}}},{\"name\":\"lower\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"lower\"}}},{\"name\":\"ignore\",\"code\":[\"{\",\" \\\"name\\\": \\\"Download_S3_URL\\\",\",\" \\\"base_class\\\": \\\"IDLTaskFromProcedure\\\",\",\" \\\"routine\\\": \\\"download_S3_URL\\\",\",\" \\\"display_name\\\": \\\"Download S3 URL\\\",\",\" \\\"description\\\": \\\"This task downloads a resource specified by an S3 URL into a local file.\\\",\",\" \\\"revision\\\": \\\"1.0.0\\\",\",\" \\\"schema\\\": \\\"idltask_1.1\\\",\",\" \\\"parameters\\\": [\",\" {\",\" \\\"name\\\": \\\"s3_url\\\",\",\" \\\"display_name\\\": \\\"S3 URL\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"INPUT\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The S3 URL to download. This must use the HTTP[S] scheme, not S3 scheme.\\\"\",\" },\",\" {\",\" \\\"name\\\": \\\"local_file\\\",\",\" \\\"display_name\\\": \\\"Local Filename\\\",\",\" \\\"type\\\": \\\"String\\\",\",\" \\\"direction\\\": \\\"input\\\",\",\" \\\"required\\\": true,\",\" \\\"description\\\": \\\"The local file in which to download the S3 resource.\\\"\",\" }\",\" ]\",\"}\"],\"config\":{\"style\":{\"control\":\"none\"}}}]}"},"auto-problem-fixing-tests":{"code.3.after-main.spec.ts":"{\"suiteName\":\"Verify tokens after main get removed on formatting\",\"fileName\":\"code.3.after-main.spec.ts\",\"tests\":[{\"name\":\"basic case\",\"code\":[\"compile_opt idl2\",\"a = $ ; comment\",\" 5\",\"end\",\"\",\"; bad\",\" worse = not 42\"]}]}","code.14.colon-in-func.spec.ts":"{\"suiteName\":\"Verify function to array for\",\"fileName\":\"code.14.colon-in-func.spec.ts\",\"tests\":[{\"name\":\"basic case\",\"code\":[\"compile_opt idl2\",\"coefs = coefs_spc(*, 0 : junk - 1)\",\"end\"]}]}","code.15.colon-in-func-method.spec.ts":"{\"suiteName\":\"Verify function method to array for\",\"fileName\":\"code.15.colon-in-func-method.spec.ts\",\"tests\":[{\"name\":\"basic case\",\"code\":[\"compile_opt idl2\",\"a = objOrStruct.var(0 : -1)\",\"end\"]}]}","code.20.return-vals-pro.spec.ts":"{\"suiteName\":\"Verify we remove excess args\",\"fileName\":\"code.20.return-vals-pro.spec.ts\",\"tests\":[{\"name\":\"for procedures\",\"code\":[\";+\",\";-\",\"pro myname\",\" compile_opt idl2\",\"\",\" ; comment\",\" return, 42\",\"\",\"end\"]},{\"name\":\"for procedure methods\",\"code\":[\";+\",\";-\",\"pro myclass::myname\",\" compile_opt idl2\",\"\",\" a = 5\",\" return, 42\",\"end\"]},{\"name\":\"for main level programs\",\"code\":[\"; main\",\"compile_opt idl2\",\"\",\"return, 42\",\"\",\"end\"]}]}","code.21.return-vals-func.spec.ts":"{\"suiteName\":\"Verify we remove excess args\",\"fileName\":\"code.21.return-vals-func.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myname\",\" compile_opt idl2\",\"\",\" ;comment\",\" ; comment\",\" return, !null, $\",\" 2, myfunc()\",\"end\"]},{\"name\":\"for function methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::myname\",\" compile_opt idl2\",\"\",\" a = 5\",\" return, !null, 2\",\"end\"]}]}","code.31.return-missing.spec.ts":"{\"suiteName\":\"Verify we add missing return statement\",\"fileName\":\"code.31.return-missing.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myname\",\" compile_opt idl2\",\"\",\" ;comment\",\"end\"]},{\"name\":\"for function methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::myname\",\" compile_opt idl2\",\"\",\" a = 5\",\"end\"]}]}","code.35.after-continuation.spec.ts":"{\"suiteName\":\"Verify tokens after line continuation get removed on formatting\",\"fileName\":\"code.35.after-continuation.spec.ts\",\"tests\":[{\"name\":\"basic case\",\"code\":[\"compile_opt idl2\",\"a = $ 5 * bad ; comment\",\" 5\",\"end\"]}]}","code.38.no-comp-opt.spec.ts":"{\"suiteName\":\"Verify we add compile opt idl2\",\"fileName\":\"code.38.no-comp-opt.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myfunc\",\"\",\" return, 1\",\"end\"]},{\"name\":\"for function methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::myfunc\",\"\",\" return, 1\",\"end\"]},{\"name\":\"for procedures\",\"code\":[\";+\",\";-\",\"pro mypro\",\"\",\"end\"]},{\"name\":\"for procedure methods\",\"code\":[\";+\",\";-\",\"pro myclass::mypro\",\"\",\"end\"]},{\"name\":\"for main case 1\",\"code\":[\"; comment\",\"\",\"end\"]},{\"name\":\"for main case 2\",\"code\":[\"a = 5\",\"\",\"end\"]},{\"name\":\"for main case 3\",\"code\":[\"\",\"; comment\",\"\",\"a = 42\",\"\",\"end\"]},{\"name\":\"for main case 4\",\"code\":[\"\",\"; comment\",\"\",\"a = 42\",\"\",\"end\"]},{\"name\":\"with args and keywords\",\"code\":[\"function myfunc,$\",\"a, b, $\",\"kw2 = kw2\",\"\",\" return, 1\",\"end\"]}]}","code.38.no-comp-opt.edge-cases.spec.ts":"{\"suiteName\":\"Verify we add compile opt idl2\",\"fileName\":\"code.38.no-comp-opt.edge-cases.spec.ts\",\"tests\":[{\"name\":\"for functions without names\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function\",\"\",\"end\"]},{\"name\":\"for procedures without names\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"pro\",\"\",\"end\"]}]}","code.38.no-comp-opt.notebooks.spec.ts":"{\"suiteName\":\"Verify we add compile opt idl2\",\"fileName\":\"code.38.no-comp-opt.notebooks.spec.ts\",\"tests\":[{\"name\":\"for functions\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myfunc\",\"\",\" return, 1\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for function methods\",\"code\":[\";+\",\"; :Returns:\",\"; any\",\";\",\";-\",\"function myclass::myfunc\",\"\",\" return, 1\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for procedures\",\"code\":[\";+\",\";-\",\"pro mypro\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for procedure methods\",\"code\":[\";+\",\";-\",\"pro myclass::mypro\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for main case 1\",\"code\":[\"; comment\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for main case 2\",\"code\":[\"a = 5\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for main case 3\",\"code\":[\"\",\"; comment\",\"\",\"a = 42\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"for main case 4\",\"code\":[\"\",\"; comment\",\"\",\"a = 42\",\"\",\"end\"],\"parseConfig\":{\"isNotebook\":true}},{\"name\":\"with args and keywords\",\"code\":[\"function myfunc,$\",\"a, b, $\",\"kw2 = kw2\",\"\",\" return, 1\",\"end\"],\"parseConfig\":{\"isNotebook\":true}}]}","code.76.init-method-pro.spec.ts":"{\"suiteName\":\"Verify we change procedure init methods to function methods\",\"fileName\":\"code.76.init-method-pro.spec.ts\",\"tests\":[{\"name\":\"without return statements\",\"code\":[\"PRO myclass2::init\",\" compile_opt idl2\",\"\",\"end\",\"\",\"\",\"pro myclass::init\",\" compile_opt idl2\",\"\",\" ; comment\",\"end\"]},{\"name\":\"with return statements\",\"code\":[\"pro myclass::init\",\" compile_opt idl2\",\"\",\" ; comment\",\" return, !null\",\"end\",\"\",\"PRO myclass2::init\",\" compile_opt idl2\",\" return\",\"end\",\"\",\"\",\"pro myclass::init\",\" compile_opt idl2\",\" return\",\"end\"]}]}","code.105.illegal-var-index.spec.ts":"{\"suiteName\":\"Verify we correctly fix brackets for indexing\",\"fileName\":\"code.105.illegal-var-index.spec.ts\",\"tests\":[{\"name\":\"for simple case\",\"code\":[\";+ my var\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt strictarr\",\"code\":[\"compile_opt strictarr\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl2\",\"code\":[\"compile_opt idl2\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]},{\"name\":\"do no change when compile opt idl3\",\"code\":[\"compile_opt idl3\",\"a = 5\",\"\",\"!null = a()\",\"\",\"end\"]}]}"},"auto-global-problem-tests":{"duplicates.spec.ts":"{\"suiteName\":\"Correctly identify duplicate problems\",\"fileName\":\"duplicates.spec.ts\",\"tests\":[{\"name\":\"while adding and removing files\",\"workspace\":\"idl/test/global-problems\",\"actions\":[{\"action\":\"add\",\"file\":\"file1.pro\"},{\"action\":\"add\",\"file\":\"file2.pro\"},{\"action\":\"add\",\"file\":\"file3.pro\"},{\"action\":\"remove\",\"file\":\"file1.pro\"},{\"action\":\"remove\",\"file\":\"file2.pro\"}]}]}","no-duplicate-main.spec.ts":"{\"suiteName\":\"Correctly ignore main level programs as duplicates\",\"fileName\":\"no-duplicate-main.spec.ts\",\"tests\":[{\"name\":\"with multiple files in the same workspace\",\"workspace\":\"idl/test/global-main-problems\",\"actions\":[{\"action\":\"add\",\"file\":\"file1.pro\"},{\"action\":\"add\",\"file\":\"file2.pro\"}]}]}"},"auto-config-resolution-tests":{"resolution.spec.ts":"{\"suiteName\":\"Correctly identify parses and returns config files\",\"fileName\":\"resolution.spec.ts\",\"tests\":[{\"name\":\"based on their folders\",\"workspace\":\"idl/test/configs\",\"actions\":[{\"action\":\"add\",\"file\":\"subdir1/idl.json\"},{\"action\":\"add\",\"file\":\"subdir2/idl.json\"},{\"action\":\"add\",\"file\":\"subdir3/idl.json\"},{\"action\":\"get\",\"file\":\"subdir1/idl.pro\"},{\"action\":\"get\",\"file\":\"subdir2/idl.pro\"},{\"action\":\"get\",\"file\":\"subdir3/idl.pro\"}]}]}","bad-file.spec.ts":"{\"suiteName\":\"Parse invalid config files\",\"fileName\":\"bad-file.spec.ts\",\"tests\":[{\"name\":\"and load default config for bad file\",\"workspace\":\"idl/test/configs\",\"actions\":[{\"action\":\"add\",\"file\":\"subdir4/idl.json\"},{\"action\":\"get\",\"file\":\"subdir4/idl.pro\"}]}]}"},"auto-task-generation-tests":{"envi.basic.spec.ts":"{\"suiteName\":\"Make basic ENVI task\",\"fileName\":\"envi.basic.spec.ts\",\"tests\":[{\"name\":\"from PRO\",\"file\":\"idl/test/task-generation/envitasktest.pro\",\"type\":\"envi\"}]}","envi.failure1.spec.ts":"{\"suiteName\":\"Don't make ENVI Task\",\"fileName\":\"envi.failure1.spec.ts\",\"tests\":[{\"name\":\"because of missing PRO definition\",\"file\":\"idl/test/task-generation/empty_envi.pro\",\"type\":\"envi\"}]}","idl.basic.spec.ts":"{\"suiteName\":\"Make basic IDL task\",\"fileName\":\"idl.basic.spec.ts\",\"tests\":[{\"name\":\"from PRO\",\"file\":\"idl/test/task-generation/idltasktest.pro\",\"type\":\"idl\"}]}","idl.failure1.spec.ts":"{\"suiteName\":\"Don't make IDL Task\",\"fileName\":\"idl.failure1.spec.ts\",\"tests\":[{\"name\":\"because of missing PRO definition\",\"file\":\"idl/test/task-generation/empty_idl.pro\",\"type\":\"idl\"}]}"}}
\ No newline at end of file
diff --git a/apps/test-tokenizer/src/test-maker/tests/auto-local-global-scope-compile-and-types-tests.interface.ts b/apps/test-tokenizer/src/test-maker/tests/auto-local-global-scope-compile-and-types-tests.interface.ts
index 04ab46e9b..58b020a9e 100644
--- a/apps/test-tokenizer/src/test-maker/tests/auto-local-global-scope-compile-and-types-tests.interface.ts
+++ b/apps/test-tokenizer/src/test-maker/tests/auto-local-global-scope-compile-and-types-tests.interface.ts
@@ -761,6 +761,31 @@ export const AUTO_LOCAL_GLOBAL_SCOPE_COMPILE_AND_TYPES_TESTS: IAutoLocalGlobalSc
},
],
},
+ {
+ suiteName: `Take first instance we encounter`,
+ fileName: `populate-structures.8.spec.ts`,
+ tests: [
+ {
+ name: 'with non-full parse',
+ code: [
+ `pro my_def__define`,
+ `compile_opt idl2`,
+ `fhdr = {WAVFILEHEADER, $`,
+ ` friff: bytarr(4), $ ; A four char string`,
+ ` fsize: 0ul, $`,
+ ` fwave: bytarr(4) $ ; A four char string`,
+ `}`,
+ ``,
+ `if ~_exists then defsysv, '!notebook_magic', {WAVFILEHEADER}`,
+ ``,
+ `end`,
+ ],
+ config: {
+ full: false,
+ },
+ },
+ ],
+ },
{
suiteName: `Correctly extract variables from`,
fileName: `procedures.spec.ts`,
diff --git a/apps/test-tokenizer/src/test-maker/tests/auto-semantic-token-tests.interface.ts b/apps/test-tokenizer/src/test-maker/tests/auto-semantic-token-tests.interface.ts
index 0df2147ab..1cdd1a8be 100644
--- a/apps/test-tokenizer/src/test-maker/tests/auto-semantic-token-tests.interface.ts
+++ b/apps/test-tokenizer/src/test-maker/tests/auto-semantic-token-tests.interface.ts
@@ -19,4 +19,22 @@ export const AUTO_SEMANTIC_TOKEN_TESTS: IAutoTest[] = [
},
],
},
+ {
+ suiteName: `Extracts semantic tokens`,
+ fileName: `complex.spec.ts`,
+ tests: [
+ {
+ name: `for complex case with out-of order and same ref`,
+ code: [
+ `compile_opt idl2`,
+ `IDLgrVolume.AddToNotebookMap`,
+ `!null = ENVI.displayinnotebookmap + ENVI.api_version`,
+ ``,
+ `IDLgrVolume.AddToNotebookMap`,
+ `ENVI.displayInNotebookMap`,
+ `end`,
+ ],
+ },
+ ],
+ },
];
diff --git a/extension/docs/problem-codes/README.md b/extension/docs/problem-codes/README.md
index da5afac39..d0ebe6c3b 100644
--- a/extension/docs/problem-codes/README.md
+++ b/extension/docs/problem-codes/README.md
@@ -46,3 +46,4 @@ If you are looking to turn off problems (i.e. don't report them), then you can u
- [idl("bad-break")](./codes/67.md)
- [idl("expected-statement")](./codes/68.md)
- [idl("illegal-var-index")](./codes/105.md)
+- [idl("circular-include")](./codes/106.md)
diff --git a/extension/docs/problem-codes/codes/106.md b/extension/docs/problem-codes/codes/106.md
new file mode 100644
index 000000000..a1022dc57
--- /dev/null
+++ b/extension/docs/problem-codes/codes/106.md
@@ -0,0 +1,27 @@
+# [IDL Problem Code:](./../README.md) `106` with alias `circular-include`
+
+> Pro tip: Include statements are an advanced concept in IDL and are not suggested for common use.
+>
+> If you are using include statements consider using a procedure or function instead.
+
+This identifies when a file that is included using `@some_file` creates a circular reference.
+
+For example, take the contents of `filea.pro` which includes the contents of file b with `@fileb`:
+
+```idl
+a = 42
+example = 'foobar-ed'
+@fileb
+; ^^ fileb imports filea and is circular
+```
+
+And the contents of `fileb.pro` which includes the contents of file a with `@filea`
+
+To correct, use brackets instead and add `compile_opt idl2` to the routine:
+
+```idl
+b = 42
+example = 'please dont do this'
+@filea
+; ^^ filea imports fileb and is circular
+```
diff --git a/idl/test/client-e2e/notebooks/envi-message-listener.idlnb b/idl/test/client-e2e/notebooks/envi-message-listener.idlnb
new file mode 100644
index 000000000..829737f18
--- /dev/null
+++ b/idl/test/client-e2e/notebooks/envi-message-listener.idlnb
@@ -0,0 +1,73 @@
+{
+ "version": "2.0.0",
+ "cells": [
+ {
+ "type": "code",
+ "content": [
+ "; start ENVI headlessly",
+ "e = envi(/headless)",
+ "",
+ "; listen to ENVI events",
+ "IDLNotebook.ListenToENVIEvents"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "File = filepath('qb_boulder_msi', subdir = ['data'], $",
+ " root_dir = e.root_dir)",
+ "Raster = e.openRaster(File)"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "task= ENVITask('ISODATAClassification')",
+ "Task.input_raster = Raster",
+ "Task.execute"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "IDLNotebook.ListenToENVIEvents, /stop"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "task= ENVITask('ISODATAClassification')",
+ "Task.input_raster = Raster",
+ "Task.execute"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "IDLNotebook.ListenToENVIEvents"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "task= ENVITask('ISODATAClassification')",
+ "Task.input_raster = Raster",
+ "Task.execute"
+ ],
+ "metadata": {},
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/idl/test/client-e2e/notebooks/problems/on-stop.idlnb b/idl/test/client-e2e/notebooks/problems/on-stop.idlnb
new file mode 100644
index 000000000..b617bac2b
--- /dev/null
+++ b/idl/test/client-e2e/notebooks/problems/on-stop.idlnb
@@ -0,0 +1,44 @@
+{
+ "version": "2.0.0",
+ "cells": [
+ {
+ "type": "code",
+ "content": [
+ "; when we have a stop or syntax error, dont stop on it and report",
+ "; cell as failed",
+ "pro mypro",
+ " compile_opt idl2",
+ " stop",
+ "end"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "; run routine with a stop",
+ "mypro"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "; dont run any cells after and mark everything as failed"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "; verify we are at the main level (one item in stack trace)",
+ "print, n_elements(scope_traceback()), /implied_print"
+ ],
+ "metadata": {},
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/idl/test/client-e2e/notebooks/problems/syntax-err1.idlnb b/idl/test/client-e2e/notebooks/problems/syntax-err1.idlnb
new file mode 100644
index 000000000..6ad3ae473
--- /dev/null
+++ b/idl/test/client-e2e/notebooks/problems/syntax-err1.idlnb
@@ -0,0 +1,23 @@
+{
+ "version": "2.0.0",
+ "cells": [
+ {
+ "type": "code",
+ "content": [
+ "; dont execute when we have syntax errors 1",
+ "a = ",
+ ""
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "; dont run any cells after and mark everything as failed"
+ ],
+ "metadata": {},
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/idl/test/client-e2e/notebooks/problems/syntax-err2.idlnb b/idl/test/client-e2e/notebooks/problems/syntax-err2.idlnb
new file mode 100644
index 000000000..896d516a8
--- /dev/null
+++ b/idl/test/client-e2e/notebooks/problems/syntax-err2.idlnb
@@ -0,0 +1,26 @@
+{
+ "version": "2.0.0",
+ "cells": [
+ {
+ "type": "code",
+ "content": [
+ "; dont execute when we have syntax errors 2",
+ "pro syntax_error",
+ " compile_opt idl2",
+ "",
+ " a = ",
+ "end"
+ ],
+ "metadata": {},
+ "outputs": []
+ },
+ {
+ "type": "code",
+ "content": [
+ "; dont run any cells after and mark everything as failed"
+ ],
+ "metadata": {},
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/idl/test/client-e2e/notebooks/test-notebook.idlnb b/idl/test/client-e2e/notebooks/test-notebook.idlnb
index 3a6642ee1..28c35e7d2 100644
--- a/idl/test/client-e2e/notebooks/test-notebook.idlnb
+++ b/idl/test/client-e2e/notebooks/test-notebook.idlnb
@@ -158,59 +158,6 @@
],
"metadata": {},
"outputs": []
- },
- {
- "type": "code",
- "content": [
- "; when we have a stop or syntax error, dont stop at it",
- "pro mypro",
- " compile_opt idl2",
- " stop",
- "end"
- ],
- "metadata": {},
- "outputs": []
- },
- {
- "type": "code",
- "content": [
- "; run routine with a stop",
- "mypro"
- ],
- "metadata": {},
- "outputs": []
- },
- {
- "type": "code",
- "content": [
- "; verify we are at the main level (one item in stack trace)",
- "print, n_elements(scope_traceback()), /implied_print"
- ],
- "metadata": {},
- "outputs": []
- },
- {
- "type": "code",
- "content": [
- "; dont execute when we have syntax errors 1",
- "a = ",
- ""
- ],
- "metadata": {},
- "outputs": []
- },
- {
- "type": "code",
- "content": [
- "; dont execute when we have syntax errors 2",
- "pro syntax_error",
- " compile_opt idl2",
- "",
- " a = ",
- "end"
- ],
- "metadata": {},
- "outputs": []
}
]
}
\ No newline at end of file
diff --git a/idl/test/scratch/notebooks/awesome_browser_ex.html b/idl/test/scratch/notebooks/awesome_browser_ex.html
new file mode 100644
index 000000000..cbaf07280
--- /dev/null
+++ b/idl/test/scratch/notebooks/awesome_browser_ex.html
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/idl/test/scratch/notebooks/awesome_browser_ex.pro b/idl/test/scratch/notebooks/awesome_browser_ex.pro
new file mode 100644
index 000000000..04dd50220
--- /dev/null
+++ b/idl/test/scratch/notebooks/awesome_browser_ex.pro
@@ -0,0 +1,89 @@
+; Copyright (c) Harris Geospatial Solutions, Inc. All rights reserved.
+;
+; -------------------------------------
+;+
+; :Arguments:
+; ev: bidirectional, required, any
+; Placeholder docs for argument, keyword, or property
+;
+;-
+pro awesome_browser_ex_event, ev
+ compile_opt idl2, hidden
+
+ widget_control, ev.top, get_uvalue = state
+
+ case tag_names(ev, /structure_name) of
+ 'WIDGET_BROWSER': begin
+ ; An event came in from JavaScript
+ if (ev.type eq 9) then begin
+ json = json_parse(ev.value)
+ if (json.HasKey('jsReady')) then begin
+ ; The Google table is ready, send the initial data
+ h = hash()
+ h['names'] = state.names
+ h['data'] = (state.data)[*, 0]
+ ; Notify the browser with the new data
+ widget_control, state.wbrowser, browser_notify = json_serialize(h)
+ endif
+ if (json.HasKey('rowSelect')) then begin
+ ; A row was selected in the table
+ rowname = json['rowSelect']
+ pArr = state.parr
+ for i = 0, 4 do begin
+ ; Update the plotline thickness highlighting the selected row
+ pArr[i].SetProperty, thick = (rowname eq state.names[i] ? 3 : 1)
+ endfor
+ endif
+ endif
+ end
+ 'WIDGET_SLIDER': begin
+ widget_control, ev.top, get_uvalue = state
+ h = hash()
+ h['data'] = (state.data)[*, ev.value - 2010]
+ ; Notify the browser with the new data
+ widget_control, state.wbrowser, browser_notify = json_serialize(h)
+ ; Update vertical plot line
+ state.p.setData, [ev.value, ev.value], [-4000, 6000]
+ end
+ else:
+ endcase
+end
+
+; --------------------------------------------------------------------
+;+
+;-
+pro awesome_browser_ex
+ compile_opt idl2, hidden
+
+ export = IDLNotebook.ExportItems()
+ if (n_elements(export) eq 0) then message, 'Nothing to embed'
+
+ asString = json_serialize(export[0], /lowercase)
+
+ ; dataFile = file_dirname(routine_filepath(), /mark_directory) + 'payload.js'
+ ; openw, lun, dataFile, /get_lun
+ ; printf, lun, 'const payload = ' + asString + ';'
+ ; free_lun, lun
+
+ ; Set up initial data
+ xsize = 600
+ ysize = 750
+ htmlfile = 'file:///' + $
+ file_dirname(routine_filepath(), /mark_directory) + 'awesome_browser_ex.html'
+
+ state = orderedhash()
+
+ ; Create widgets
+ wTLB = widget_base(/column, xsize = xsize, uvalue = state)
+ wBrowser = widget_browser(wTLB, value = htmlfile, xsize = xsize, ysize = ysize)
+ state['wBrowser'] = wBrowser
+ widget_control, wTLB, /realize
+ xmanager, 'awesome_browser_ex', wTLB, /no_block
+
+ ; need to stop here so the interpreter gets a chance to catch up
+ ; something weird with evet order in the browser
+ stop
+
+ ; send data
+ widget_control, wBrowser, browser_notify = asString
+end
\ No newline at end of file
diff --git a/idl/test/scratch/notebooks/idl-1.0.0.js b/idl/test/scratch/notebooks/idl-1.0.0.js
new file mode 100644
index 000000000..405da29d2
--- /dev/null
+++ b/idl/test/scratch/notebooks/idl-1.0.0.js
@@ -0,0 +1,69 @@
+/*
+ IDL class to handle notifications to/from IDL.
+ Used by WIDGET_BROWSER.
+
+ Note: This code only needs to run in the Chromium browser, so we don't
+ have to worry about cross-browser differences with CustomEvent.
+
+ Examples:
+ 1. Send a notification from JavaScript to IDL:
+ IDL.notifyIDL("my message payload");
+
+ 2. Register to receive notifications from IDL:
+ IDL.addEventListener(myIDLListener);
+ var myIDLListener = function(event)
+ {
+ var idlValue = JSON.parse(event.detail);
+ ...
+ };
+*/
+if (typeof IDL === "undefined") {
+ var IDL =
+ {
+ /*
+ Send a notification from JavaScript to IDL.
+ value: A string containing the message payload.
+
+ Usage:
+ IDL.notifyIDL("my message payload");
+ */
+ notifyIDL: function(value)
+ {
+ window.cefQuery({
+ request: value,
+ persistent: false,
+ onSuccess: function(response) {
+ // Do nothing
+ },
+ onFailure: function(error_code, error_message) {
+ console.log(error_message);}
+ });
+ }
+
+ /*
+ Receive a notification from IDL and route to the listeners.
+ This is called from the IDL C code; the user should never need
+ to use this method directly.
+ */
+ , notifyJS: function(value)
+ {
+ var event = new CustomEvent('IDLNotify',{'detail':value});
+ document.dispatchEvent(event);
+ }
+
+ /*
+ Register a listener to receive notifications from IDL.
+
+ listener: an object to receive the event notification.
+ This should either be an object implementing the
+ EventListener interface, or a JavaScript function.
+ The event.detail will contain the IDL message payload.
+
+ Usage:
+ IDL.addEventListener(myIDLListener);
+ */
+ , addEventListener: function(listener) {
+ document.addEventListener("IDLNotify", listener);
+ }
+ };
+}
diff --git a/idl/test/scratch/notebooks/new_plot.pro b/idl/test/scratch/notebooks/new_plot.pro
new file mode 100644
index 000000000..f225d0e85
--- /dev/null
+++ b/idl/test/scratch/notebooks/new_plot.pro
@@ -0,0 +1,250 @@
+;+
+; :Returns: Structure
+;
+; :Arguments:
+; m1: in, required, Number
+; First pendulum wieght
+; l1: in, required, Number
+; First arm length
+; th01: in, required, Number
+; First pendulum start angle
+; dth01: in, required, Number
+; First pendulum start anglular speed
+; m2: in, required, Number
+; Second pendulum weight
+; l2: in, required, Number
+; Second arm length
+; th02: in, required, Number
+; Second pendulum start angle
+; dth02: in, required, Number
+; Second pendulum start anglular speed
+; dT: in, required, Number
+; Delta-t
+; n: in, required, Number
+; Number of steps
+; g: in, required, Number
+; Gravity
+;
+;-
+function AwesomeDoublePendulumProCode, m1, l1, th01, dth01, m2, l2, th02, dth02, dT, n, g
+ compile_opt idl2, hidden
+ on_error, 2
+
+ ;+ Angular position of pendulum 1
+ th1 = make_array(n, type = 5, /nozero)
+
+ ;+ Angular velocity of pendulum 1
+ thd1 = make_array(n, type = 5, /nozero)
+
+ ;+ Angular acceleration of pendulum 1
+ thdd1 = make_array(n, type = 5, /nozero)
+
+ ;+ Angular position of pendulum 2
+ th2 = make_array(n, type = 5, /nozero)
+
+ ;+ Angular velocity of pendulum 2
+ thd2 = make_array(n, type = 5, /nozero)
+
+ ;+ Angular acceleration of pendulum 2
+ thdd2 = make_array(n, type = 5, /nozero)
+
+ ;+ Total energy (kinetic?)
+ Ttot = make_array(n, type = 5, /nozero)
+
+ ;+ Total enegery (potential)
+ Utot = make_array(n, type = 5, /nozero)
+
+ ;+ Pendulum 1 start deets
+ th1[0] = th01 * !dtor
+ thd1[0] = dth01 * !dtor
+
+ ;+ Pendulum 2 start deets
+ th2[0] = th02 * !dtor
+ thd2[0] = dth02 * !dtor
+
+ ; simulate
+ for i = 0, n - 2 do begin
+ ; calculate our energies
+ Ttot[i] = 0.5 * m1 * ((thd1[i]) ^ 2) * (l1 ^ 2) + $
+ 0.5 * m2 * ((thd1[i] ^ 2) * (l1 ^ 2) + $
+ (thd2[i] ^ 2) * (l2 ^ 2) + 2 * thd1[i] * thd2[i] * l1 * l2 * cos(th1[i] - th2[i]))
+ Utot[i] = -g * l1 * (m1 + m2) * cos(th1[i]) - m2 * l2 * g * cos(th2[i])
+
+ ; calculate our first angular acceleration
+ top1 = -m2 * l1 * (thd1[i] ^ 2) * sin(th1[i] - th2[i]) * cos(th1[i] - th2[i]) + $
+ g * m2 * sin(th2[i]) * cos(th1[i] - th2[i]) - $
+ m2 * l2 * (thd2[i] ^ 2) * sin(th1[i] - th2[i]) - $
+ (m1 + m2) * g * sin(th1[i])
+ bottom1 = l1 * (m1 + m2) - m2 * l1 * (cos(th1[i] - th2[i]) ^ 2)
+ thdd1[i] = top1 / bottom1
+
+ ; calcualte our second angular acceleration
+ top2 = m2 * l2 * (thd2[i] ^ 2) * sin(th1[i] - th2[i]) * cos(th1[i] - th2[i]) + $
+ g * sin(th1[i]) * cos(th1[i] - th2[i]) * (m1 + m2) + $
+ l1 * (thd1[i] ^ 2) * sin(th1[i] - th2[i]) * (m1 + m2) - $
+ g * sin(th2[i]) * (m1 + m2)
+ bottom2 = l2 * (m1 + m2) - m2 * l2 * (cos(th1[i] - th2[i]) ^ 2)
+ thdd2[i] = top2 / bottom2
+
+ ; do our numeric integration
+ thd1[i + 1] = dT * thdd1[i] + thd1[i]
+ thd2[i + 1] = dT * thdd2[i] + thd2[i]
+ th1[i + 1] = th1[i] + dT * thd1[i] + .5 * (dT ^ 2) * thdd1[i]
+ th2[i + 1] = th2[i] + dT * thd2[i] + .5 * (dT ^ 2) * thdd2[i]
+ endfor
+
+ ;+ X position of first pendulum
+ x1 = l1 * sin(th1)
+
+ ;+ Y position of first pendulum
+ y1 = -l1 * cos(th1)
+
+ ;+ X position of second pendulum
+ x2 = x1 + l2 * sin(th2)
+
+ ;+ Y position of second pendulum
+ y2 = y1 - l2 * cos(th2)
+
+ ; get the total energy
+ Etot = Ttot + Utot
+ Eerror = Etot - Etot[0]
+
+ return, {x1: x1, y1: y1, x2: x2, y2: y2, etot: Etot, eerror: Eerror}
+end
+
+; mian level program
+compile_opt idl2
+
+;+
+; Parameters related to the length of our simulation
+;-
+
+;+ Max time (seconds)
+maxT = 10.0
+
+;+ delta time between frames
+dT = 0.0001d
+
+;+ number of frames
+n = ceil(double(maxT) / dT)
+
+;+ animation frame rate
+fps = 60
+
+;+ goal dt between frames
+dTGoal = 1d / fps
+
+;+ The frequency of frames that we play from our simulation for 60 FPS
+frameSpacing = floor(dTGoal / dT) > 1
+
+;+ Strength of gravity (m/s^2)
+g = 3d
+
+;+ First pendulum start angle (degrees)
+th01 = 90
+
+;+ First pendulum angular velocity (degrees/second)
+dth01 = 42
+
+;+ Mass of pendulum 1 (kg)
+m1 = 0.5
+
+;+ Length of pendulum 1 arm (meters)
+L1 = 0.5
+
+;+ Second pendulum start angule (degrees)
+th02 = 30
+
+;+ Second pendulum angular velocity (degrees/second)
+dth02 = -360
+
+;+ Mass of pendulum 2 (kg)
+m2 = 2
+
+;+ Length of pendulum arm 2 (meters)
+L2 = 0.5
+
+;+ max range of our pendulum
+range = (L1 + L2) * [-1, 1]
+
+;+ Simulate!
+results = AwesomeDoublePendulumProCode( $
+ m1, L1, th01, dth01, $
+ m2, L2, th02, dth02, dT, $
+ n, g)
+
+;+
+; Unpack our results
+;-
+
+;+ X position of first pendulum
+x1 = results.x1
+
+;+ Y position of first pendulum
+y1 = results.y1
+
+;+ X position of second pendulum
+x2 = results.x2
+
+;+ Y position of second pendulum
+y2 = results.y2
+
+; get the total energy
+Etot = results.etot
+Eerror = results.eerror
+
+;+ Data for pendulum arms
+lines = {IDLNotebookPlot_LineAnimation, $
+ properties: orderedhash(), $
+ frames: list()}
+
+;+ Data for our pendulums
+pendulums = {IDLNotebookPlot_BubbleAnimation, $
+ properties: orderedhash(), $
+ frames: list()}
+
+;+ Create sizes of pendulums
+if (m1 gt m2) then begin
+ sizes = list(20, 20 * sqrt(m2 / m1))
+endif else begin
+ sizes = list(20 * sqrt(m1 / m2), 20)
+endelse
+
+;+ Get the indices for the frames we want to display
+frames = [0 : n - 1 : frameSpacing]
+foreach i, frames do begin
+ ; add our frame
+ lines.frames.add, {IDLNotebookPlot_LineFrame, $
+ x: list(0, x1[i], x2[i]), $
+ y: list(0, y1[i], y2[i])}
+
+ ; add our frame
+ pendulums.frames.add, {IDLNotebookPlot_BubbleFrame, $
+ x: list(x1[i], x2[i]), $
+ y: list(y1[i], y2[i]), $
+ r: sizes}
+endforeach
+
+;+ Create chart propreties- CASE SENSITIVE
+props = orderedhash()
+props['frameInterval'] = 1000 / fps ; ms per frame
+props['aspectRatio'] = 1
+
+; get axis range
+scale = orderedhash('min', range[0] * 1.25, 'max', range[1] * 1.25)
+
+; set axis range
+props['scales'] = orderedhash('x', scale, 'y', scale)
+
+;+ Create notebook plot
+plot = {IDLNotebookPlot, $
+ properties: props, $
+ data: list(pendulums, lines)}
+
+;+ Add to our notebook
+IDLNotebook.AddToNotebook, plot
+
+; plot in our browser
+awesome_browser_ex
+
+end
\ No newline at end of file
diff --git a/idl/vscode/notebooks/envi/envi__displayrasterinnotebook.pro b/idl/vscode/notebooks/envi/envi__displayrasterinnotebook.pro
index dac321b68..2399875d3 100644
--- a/idl/vscode/notebooks/envi/envi__displayrasterinnotebook.pro
+++ b/idl/vscode/notebooks/envi/envi__displayrasterinnotebook.pro
@@ -71,18 +71,19 @@ pro envi::displayRasterInNotebook, raster, size = size
; process each raster
for i = 0, nRasters - 1 do begin
- ; convert raster to thumbnail
- task = ENVITask('GenerateThumbnail')
- task.input_raster = useRasters[i]
- task.thumbnail_size = size
- task.execute
+ ; make thumbnail
+ uri = !null
+ AwesomeGenerateThumbnail, $
+ input_raster = useRasters[i], $
+ thumbnail_size = size, $
+ output_png_uri = uri
; save URI
- uris[i] = task.output_raster_uri
+ uris[i] = uri
; get info about PNG to display correctly
if (i eq 0) then begin
- !null = query_png(task.output_raster_uri, info)
+ !null = query_png(uri, info)
endif
endfor
diff --git a/idl/vscode/notebooks/envi/helpers/awesomegeneratethumbnail.pro b/idl/vscode/notebooks/envi/helpers/awesomegeneratethumbnail.pro
index bfad19a6d..fadd8c7bf 100644
--- a/idl/vscode/notebooks/envi/helpers/awesomegeneratethumbnail.pro
+++ b/idl/vscode/notebooks/envi/helpers/awesomegeneratethumbnail.pro
@@ -25,7 +25,7 @@ end
;+
; :Keywords:
-; input_raster: in, optional, any
+; input_raster: in, optional, ENVIRaster
; Placeholder docs for argument, keyword, or property
; no_stretch: in, optional, Boolean
; If set, don't stretch data
@@ -69,12 +69,16 @@ pro AwesomeGenerateThumbnail, $
dimensions = data.dim
nChannels = (n_elements(dimensions) eq 2) ? 1 : 3
+ ; check for data ignore - this is not honored for classification images
+ if inputRaster.metadata.hasTag('data ignore value') then begin
+ pixelState += data eq inputRaster.metadata['data ignore value']
+ endif
+
+ ; flatten pixel state
+ if (nChannels gt 1) then pixelState = total(pixelState, 3, /integer)
+
; Assign bad pixels to alpha band
- alpha = bytarr(dimensions[0], dimensions[1])
- for i = 0, nChannels - 1 do begin
- alpha or= (pixelState[*, *, i] gt 0)
- endfor
- alpha = (alpha xor 1) * 255b
+ alpha = (pixelState eq 0) * 255b
; Dealing with images that have a colormap
inputRaster.GetProperty, colormap = colormap
@@ -93,7 +97,7 @@ pro AwesomeGenerateThumbnail, $
endif
; Linear Stretch from histogram
- if (~isa(colormap, 'EnviColorMap') && ~keyword_set(no_stretch)) then begin
+ if (~isa(colormap, 'EnviColorMap') && (inputRaster.data_type ne 'byte')) then begin
histData = bytarr(dimensions[0], dimensions[1], 3, /nozero)
for i = 0, 2 do begin
band = data[*, *, i]
diff --git a/idl/vscode/notebooks/envi/helpers/roi_parse.pro b/idl/vscode/notebooks/envi/helpers/roi_parse.pro
index be0ee47f0..55dd60859 100644
--- a/idl/vscode/notebooks/envi/helpers/roi_parse.pro
+++ b/idl/vscode/notebooks/envi/helpers/roi_parse.pro
@@ -134,6 +134,9 @@ function ROI_Parse, roi_uri, debug = debug
coordsNodes = geo.GetElementsByTagName('Coordinates')
nCoords = coordsNodes.GetLength()
+ ; skip if nothing
+ if (nCoords eq 0) then continue
+
; process only if we have data
if (nCoords gt 0) then begin
; count how many we filled
diff --git a/idl/vscode/notebooks/envi/helpers/shapefiletogeojson.pro b/idl/vscode/notebooks/envi/helpers/shapefiletogeojson.pro
index dba1fd10c..e34c39f8b 100644
--- a/idl/vscode/notebooks/envi/helpers/shapefiletogeojson.pro
+++ b/idl/vscode/notebooks/envi/helpers/shapefiletogeojson.pro
@@ -1,3 +1,27 @@
+;+
+; :Returns: String
+;
+; :Arguments:
+; item: in, required, any
+; The item that we are saving
+;
+;-
+function ShapeFileToGeoJSON_Serialize, item
+ compile_opt idl2, hidden
+
+ ; check what our IDL version is
+ case (!true) of
+ ;+
+ ; Support for precision keyword
+ ;-
+ long(!version.release.replace('.', '')) ge 883: return, json_serialize(item, /lowercase, precision = 8)
+ ;+
+ ; We don't so we can't print
+ ;-
+ else: return, json_serialize(item, /lowercase)
+ endcase
+end
+
;+
; :Tooltip:
; Converts shapefiles to GeoJSON
@@ -279,16 +303,16 @@ pro ShapeFileToGeoJSON, $
; how do we proceed
case (1) of
((types[idx] eq 'Polygon') && (~multipoints[idx])): begin
- strs.Add, '{"type":"Feature","properties":' + fixed[z] + ',"geometry":{"type":"' + types[idx] + '","coordinates":' + json_serialize(list(vert), precision = 8) + '}}'
+ strs.Add, '{"type":"Feature","properties":' + fixed[z] + ',"geometry":{"type":"' + types[idx] + '","coordinates":' + ShapeFileToGeoJSON_Serialize(list(vert)) + '}}'
end
(types[idx] eq 'Point' && (n_elements(vert) eq 1)): begin
- strs.Add, '{"type":"Feature","properties":' + fixed[z] + ',"geometry":{"type":"' + types[idx] + '","coordinates":' + json_serialize(vert[0], precision = 8) + '}}'
+ strs.Add, '{"type":"Feature","properties":' + fixed[z] + ',"geometry":{"type":"' + types[idx] + '","coordinates":' + ShapeFileToGeoJSON_Serialize(vert[0]) + '}}'
end
(types[idx] eq 'LineString'): begin
- strs.Add, '{"type":"Feature","properties":' + fixed[z] + ',"geometry":{"type":"' + types[idx] + '","coordinates":' + json_serialize(vert[0], precision = 8) + '}}'
+ strs.Add, '{"type":"Feature","properties":' + fixed[z] + ',"geometry":{"type":"' + types[idx] + '","coordinates":' + ShapeFileToGeoJSON_Serialize(vert[0]) + '}}'
end
else: begin
- strs.Add, '{"type":"Feature","properties":' + fixed[z] + ',"geometry":{"type":"' + types[idx] + '","coordinates":' + json_serialize(vert, precision = 8) + '}}'
+ strs.Add, '{"type":"Feature","properties":' + fixed[z] + ',"geometry":{"type":"' + types[idx] + '","coordinates":' + ShapeFileToGeoJSON_Serialize(vert) + '}}'
end
endcase
endforeach
diff --git a/idl/vscode/notebooks/envi/vscodeenvimessageinterceptor__define.pro b/idl/vscode/notebooks/envi/vscodeenvimessageinterceptor__define.pro
new file mode 100644
index 000000000..cf7c0b8f1
--- /dev/null
+++ b/idl/vscode/notebooks/envi/vscodeenvimessageinterceptor__define.pro
@@ -0,0 +1,160 @@
+;+
+; :Description:
+; Creates our message interceptor and registers it with ENVI (requires that ENVI is launched)
+;
+; :Returns: VSCodeENVIMessageInterceptor
+;
+; :Keywords:
+; verbose: in, optional, Boolean
+; If set, we print out all progress messages, otherwise we only print
+; the first one and not any child task messages.
+;
+;-
+function VSCodeENVIMessageInterceptor::Init, verbose = verbose
+ compile_opt idl2, hidden
+ on_error, 2
+
+ ; get the current ENVI session
+ e = envi(/current)
+
+ ; validate ENVI has started stop
+ if (e eq !null) then message, 'ENVI has not started yet, required!', level = -1
+
+ ; init super
+ if (~self.ENVIMessageHandler::Init()) then begin
+ return, 0
+ endif
+
+ ; init properties
+ self.stack = 0
+ self.verbose = keyword_set(verbose)
+ self.laststart = list()
+ self.lastprogress = list()
+
+ ; get the channel and subscribe
+ oChannel = e.GetBroadcastChannel()
+ oChannel.Subscribe, self
+
+ ; return 1 as valid object
+ return, 1
+end
+
+;+
+; :Description:
+; Cleans up our message interceptor
+;
+;-
+pro VSCodeENVIMessageInterceptor::Cleanup
+ compile_opt idl2, hidden
+ on_error, 2
+
+ ; clean up super
+ self.ENVIMessageHandler::Cleanup
+
+ ; get ENVI
+ e = envi(/current)
+
+ ; make sure valid
+ if (e ne !null) then begin
+ oChannel = e.GetBroadcastChannel()
+ if (obj_valid(oChannel)) then oChannel.Unsubscribe, self
+ endif
+end
+
+;+
+; :Description:
+; Handle intercepted messages from ENVI
+;
+; :Arguments:
+; msg: in, required, ENVIStartMessage | ENVIProgressMessage | ENVIFinishMessage
+; Placeholder docs for argument, keyword, or property
+;
+;-
+pro VSCodeENVIMessageInterceptor::OnMessage, msg
+ compile_opt idl2, hidden
+ on_error, 2
+
+ ; get the indent size
+ indent = self.stack eq 0 ? '' : strjoin(replicate(' ', self.stack))
+
+ ; handle our different messages
+ case (!true) of
+ ;+
+ ; Start of progress
+ ;-
+ isa(msg, 'ENVIStartMessage'): begin
+ if (n_elements(self.laststart) gt 0) then begin
+ if (self.laststart[-1] eq msg.message) then return
+ endif
+
+ self.stack++
+
+ ;+ get the message we print
+ useMsg = (msg.message.replace('Task', '')).replace('task', '')
+
+ if (self.stack eq 1 || self.stack gt 1 and self.verbose) then $
+ print, indent + useMsg.trim()
+
+ ; track info about progress
+ self.laststart.add, msg.message
+ self.lastprogress.add, -1
+ end
+
+ ;+
+ ; Progress message for what we are running
+ ;-
+ isa(msg, 'ENVIProgressMessage'): begin
+ ; return if same as last
+ if (msg.percent le self.lastprogress[self.stack - 1]) then return
+
+ ; track current progress
+ self.lastprogress[self.stack - 1] = msg.percent
+
+ if (self.stack eq 1 || self.stack gt 1 and self.verbose) then $
+ print, strjoin([indent, msg.message.trim(), ', Progress=', strtrim(long(msg.percent), 2), '%'])
+ end
+
+ ;+
+ ; Progress bar finished
+ ;-
+ isa(msg, 'ENVIFinishMessage'): begin
+ ; ; update stack count
+ self.stack--
+
+ ; remove last progress
+ self.laststart.remove
+ self.lastprogress.remove
+
+ ; attempt to print
+ if (self.stack eq 0 || self.stack gt 0 and self.verbose) then begin
+ print, strmid(indent, 2) + 'Finished!'
+ print
+ endif
+ end
+
+ else: ; do nothing
+ endcase
+end
+
+;+
+; :VSCodeENVIMessageInterceptor:
+; lastprogress: List
+; Track the previous progress percentage
+; laststart: List
+; Titles of start messages to filter duplicates
+; stack: Long
+; The number of pending progress bars
+; verbose: Boolean
+; If we print all messages or not
+;
+;-
+pro VSCodeENVIMessageInterceptor__define
+ compile_opt idl2, hidden
+ on_error, 2
+ !null = {VSCodeENVIMessageInterceptor, $
+ inherits ENVIMessageHandler, $
+ stack: 0l, $
+ laststart: list(), $
+ lastprogress: list(), $
+ verbose: !false}
+end
\ No newline at end of file
diff --git a/idl/vscode/notebooks/idlnotebook/idlnotebook__define.pro b/idl/vscode/notebooks/idlnotebook/idlnotebook__define.pro
index 904388416..2ae0f937a 100644
--- a/idl/vscode/notebooks/idlnotebook/idlnotebook__define.pro
+++ b/idl/vscode/notebooks/idlnotebook/idlnotebook__define.pro
@@ -155,7 +155,7 @@ pro IDLNotebook::AddToNotebook, item
; make sure all files exist
foreach uri, item.uris do begin
if ~file_test(uri) then begin
- mesage, 'File does not exist: "' + uri + '"', level = -1
+ message, 'File does not exist: "' + uri + '"', level = -1
endif
endforeach
@@ -174,7 +174,7 @@ pro IDLNotebook::AddToNotebook, item
isa(item, 'IDLNotebookImage_FromUri'): begin
; validate
if ~file_test(item.uri) then begin
- mesage, 'File does not exist: "' + item.uri + '"', level = -1
+ message, 'File does not exist: "' + item.uri + '"', level = -1
endif
; track
@@ -189,7 +189,7 @@ pro IDLNotebook::AddToNotebook, item
;+
; Check for 2D plot
;-
- isa(item, 'IDLNotebookPlot2D'): IDLNotebookPlot2D._AddToNotebook, item
+ isa(item, 'IDLNotebookPlot'): IDLNotebookPlot._AddToNotebook, item
;+
; Throw error because we don't know what we are adding or handling
@@ -217,26 +217,26 @@ function IDLNotebook::_CreateNotebookItemProps, item
; validate input
if ~arg_present(item) then message, 'Item not specified, required!', level = -1
- ;+ get properties
- props = orderedhash(item, /lowercase)
-
; output properties
- saveProps = orderedhash(/fold_case)
+ saveProps = orderedhash()
+
+ ; get structure key names
+ keys = tag_names(item)
; remove any non-truthy items
- foreach val, props, key do begin
+ foreach key, keys, i do begin
catch, err
if (err ne 0) then begin
catch, /cancel
continue
endif
- val = props[key]
+ val = item.(i)
catch, /cancel
case (!true) of
; remove null strings
- isa(val, 'struct'): saveProps[key] = IDLNotebook._CreateNotebookItemProps(val)
+ isa(val, 'struct'): saveProps[key.toLower()] = IDLNotebook._CreateNotebookItemProps(val)
; remove if !null
isa(val, /null): ; do nothing
@@ -248,7 +248,7 @@ function IDLNotebook::_CreateNotebookItemProps, item
isa(val, /string) and ~val: ; do nothing
; save
- else: saveProps[key] = val
+ else: saveProps[key.toLower()] = val
endcase
endforeach
@@ -280,14 +280,10 @@ function IDLNotebook::_CreateNotebookItem, item
end
;+
-; :Description:
-; Exports (to the console via print) all of the magic items that
-; we are currently tracking
-;
-; Cleans up and removes everything after we have exported
+; :Returns: any
;
;-
-pro IDLNotebook::Export
+function IDLNotebook::ExportItems
compile_opt idl2, hidden, static
on_error, 2
@@ -311,7 +307,6 @@ pro IDLNotebook::Export
catch, err
if (err ne 0) then begin
catch, /cancel
- help, /last_message
message, /reissue_last
endif
@@ -358,8 +353,36 @@ pro IDLNotebook::Export
; clean up
IDLNotebook.Reset
- ; print
- print, json_serialize(export, /lowercase)
+ ;+ Return the items to embed
+ return, export
+end
+
+;+
+; :Description:
+; Exports (to the console via print) all of the magic items that
+; we are currently tracking
+;
+; Cleans up and removes everything after we have exported
+;
+;-
+pro IDLNotebook::Export
+ compile_opt idl2, hidden, static
+ on_error, 2
+
+ ;+ Export items and convert to something that is serializable
+ export = IDLNotebook.ExportItems()
+
+ ; check what our IDL version is
+ case (!true) of
+ ;+
+ ; Support for precision keyword
+ ;-
+ long(!version.release.replace('.', '')) ge 883: print, json_serialize(export, /lowercase, precision = 8)
+ ;+
+ ; We don't so we can't print
+ ;-
+ else: print, json_serialize(export, /lowercase)
+ endcase
end
;+
@@ -383,6 +406,32 @@ function IDLNotebook::Init, _extra = extra
return, 1
end
+;+
+; :Description:
+; Registers a message interceptor for ENVI progress messages to have
+; some basic user feedback in notebooks
+;
+; :Keywords:
+; stop: in, optional, Boolean
+; If set, and we are listening to events from ENVI, removes our event
+; listener and cleans up
+;
+;-
+pro IDLNotebook::ListenToENVIEvents, stop = stop
+ compile_opt idl2, hidden, static
+ on_error, 2
+
+ ; return if already registered
+ if (obj_valid(!idlnotebookmagic.envilistener)) then begin
+ ; stop listening to events
+ if keyword_set(stop) then !idlnotebookmagic.envilistener.cleanup
+ return
+ endif
+
+ ; create message interceptor and save
+ !idlnotebookmagic.envilistener = VSCodeENVIMessageInterceptor()
+end
+
;+
; :Description:
; Resets properties and clears all tracked items
@@ -395,6 +444,7 @@ pro IDLNotebook::Reset
; clean up our objects
!idlnotebookmagic.items.remove, /all
!idlnotebookmagic.graphics.remove, /all
+ !idlnotebookmagic.mapitems.remove, /all
; clear any IDs for the window that we have currently embedded
!magic.window = -1
@@ -421,6 +471,8 @@ end
; Class definition procedure
;
; :IDLNotebook:
+; envilistener: VSCodeENVIMessageInterceptor
+; If we have created an ENVI listener or not
; graphics: OrderedHash
; By window ID, track graphics that we need to embed
; items: List
@@ -449,6 +501,7 @@ pro IDLNotebook__define
; Data structure for this class
;-
!null = {IDLNotebook, $
+ envilistener: obj_new(), $
items: list(), $
mapitems: list(), $
graphics: orderedhash()}
@@ -469,10 +522,10 @@ pro IDLNotebook__define
; make sure super magic exists
defsysv, '!IDLNotebookMagic', exists = _exists
if ~_exists then defsysv, '!IDLNotebookMagic', $
- {IDLNotebook, items: list(), mapitems: list(), graphics: orderedhash(/fold_case)}
+ {IDLNotebook, envilistener: !false, items: list(), mapitems: list(), graphics: orderedhash(/fold_case)}
; load all other structures
IDLNotebookImage__define
IDLNotebookMap__define
- IDLNotebookPlot2D__define
+ IDLNotebookPlot__define
end
\ No newline at end of file
diff --git a/idl/vscode/notebooks/idlnotebook/idlnotebookmap__define.pro b/idl/vscode/notebooks/idlnotebook/idlnotebookmap__define.pro
index e4acf013b..e569a2980 100644
--- a/idl/vscode/notebooks/idlnotebook/idlnotebookmap__define.pro
+++ b/idl/vscode/notebooks/idlnotebook/idlnotebookmap__define.pro
@@ -10,6 +10,9 @@ function IDLNotebookMap::_CreateNotebookItem, val
compile_opt idl2, hidden, static
on_error, 2
+ ;+
+ ; See what we are trying to add to our map
+ ;-
case (!true) of
;+
; Handle raw GeoJSON
@@ -65,18 +68,19 @@ function IDLNotebookMap::_CreateNotebookItem, val
reproj = ENVIReprojectRaster(val.raster, $
coord_sys = ENVICoordSys(coord_sys_code = 3857))
- ; convert raster to thumbnail
- task = ENVITask('GenerateThumbnail')
- task.input_raster = reproj
- task.thumbnail_size = 1024
- task.execute
+ ; make thumbnail
+ uri = !null
+ AwesomeGenerateThumbnail, $
+ input_raster = reproj, $
+ thumbnail_size = 1024, $
+ output_png_uri = uri
; get info about PNG to display correctly
- !null = query_png(task.output_raster_uri, info)
+ !null = query_png(uri, info)
; make new item
newItem = {IDLNotebookMap_ImageFromUri}
- newItem.uri = task.output_raster_uri
+ newItem.uri = uri
newItem.xsize = info.dimensions[0]
newItem.ysize = info.dimensions[1]
newItem.extents = reproj.getExtents()
@@ -155,6 +159,10 @@ function IDLNotebookMap::_CreateNotebookItem, val
; save because we are OK!
return, IDLNotebook._CreateNotebookItem(newItem)
end
+
+ ;+
+ ; Unknown data type that we can't handle
+ ;-
else: begin
message, 'Found an unsupported data type in list of items to add to map', level = -1
end
diff --git a/idl/vscode/notebooks/idlnotebook/idlnotebookplot2d__define.pro b/idl/vscode/notebooks/idlnotebook/idlnotebookplot2d__define.pro
deleted file mode 100644
index c454c8ae1..000000000
--- a/idl/vscode/notebooks/idlnotebook/idlnotebookplot2d__define.pro
+++ /dev/null
@@ -1,59 +0,0 @@
-;+
-; :Description:
-; Static method that adds a 2D plot to an IDL Notebook
-;
-; This specific method manages the validation of the data and should
-; only be added through the `IDLNotebook::AddToNotebook` method
-;
-; :Arguments:
-; item: in, required, IDLNotebookPlot2D
-; The plot data for notebooks
-;
-;-
-pro IDLNotebookPlot2D::_AddToNotebook, item
- compile_opt idl2, hidden, static
- on_error, 2
-
- ; validate input
- if ~isa(item, 'IDLNotebookPlot2D') then begin
- message, 'Expected input argument to be an IDLNotebookPlot2D structure', level = -1
- endif
-
- ;+ Number of y elements
- nY = item.y.length
- if (nY eq 0) then message, 'No Y data values specified, required!', level = -1
-
- ; make sure valid
- if ~obj_valid(item.x) then item.x = list(ulindgen(item.y.length), /extract)
-
- ; check if we need to set the x values
- if (item.x.length eq 0) then begin
- item.x = list(ulindgen(item.y.length), /extract)
- endif
-
- ; track data
- IDLNotebook._TrackNotebookItem, item
-end
-
-;+
-; :IDLNotebookPlot2D:
-; x: List