From 0f606b62822a5eb1707977a51819e3d9e5ebf561 Mon Sep 17 00:00:00 2001 From: Chet Joswig Date: Fri, 8 Nov 2024 16:05:38 -0800 Subject: [PATCH] Show variables and globals in form view (#1536) * support for seqN variables in form view * scope vml variables and parameters pulled in * return globals even if parse tree is unavailable * pull isVariable check into reactive block * reuse isDefined function * toggle between literal and reference option * change term reference to symbol * readability of enable repeat args check * don't use symbol for boolean test * pr feedback reactive statement not triggered * pr feedback - combine template literals where possible * pr feedback variable name * use filterEmpty instead of new duplicate function * move CSS attribute to parent, playwrigth selector update * ensure functions called in reactive statements only depend on parameters * remove extraneous optional chain * more descriptive test names * pr feedback, delete useQuotes option and format in ArgEditor --- e2e-tests/fixtures/Sequence.ts | 2 +- .../sequencing/SequenceEditor.svelte | 7 +- .../sequencing/form/ArgEditor.svelte | 101 +++++++++++++----- .../sequencing/form/ArgTitle.svelte | 88 ++++++++++++--- .../sequencing/form/EnumEditor.svelte | 12 +-- .../sequencing/form/SelectedCommand.svelte | 66 +++++++++--- src/utilities/codemirror/commandInfoMapper.ts | 17 ++- src/utilities/codemirror/seq-n-tree-utils.ts | 20 +++- src/utilities/codemirror/vml/vmlAdaptation.ts | 8 +- .../codemirror/vml/vmlBlockLibrary.ts | 7 +- src/utilities/codemirror/vml/vmlConstants.ts | 4 + src/utilities/codemirror/vml/vmlFormatter.ts | 10 +- .../codemirror/vml/vmlTreeUtils.test.ts | 64 ++++++++++- src/utilities/codemirror/vml/vmlTreeUtils.ts | 59 +++++++++- .../sequence-editor/sequence-linter.ts | 2 +- src/utilities/sequence-editor/tree-utils.ts | 6 +- 16 files changed, 384 insertions(+), 89 deletions(-) diff --git a/e2e-tests/fixtures/Sequence.ts b/e2e-tests/fixtures/Sequence.ts index 9a01ce501a..55e588b2c8 100644 --- a/e2e-tests/fixtures/Sequence.ts +++ b/e2e-tests/fixtures/Sequence.ts @@ -168,7 +168,7 @@ export class Sequence { await expect(this.command).toHaveText('C FSW_CMD_0 "ON" false 1'); await this.page .locator('fieldset') - .filter({ hasText: 'enum_arg_0 ONOFF' }) + .filter({ hasText: 'enum_arg_0 Value Type Literal' }) .getByRole('combobox') .selectOption('OFF'); diff --git a/src/components/sequencing/SequenceEditor.svelte b/src/components/sequencing/SequenceEditor.svelte index e7850a9118..33c1d6756d 100644 --- a/src/components/sequencing/SequenceEditor.svelte +++ b/src/components/sequencing/SequenceEditor.svelte @@ -6,7 +6,7 @@ import { lintGutter } from '@codemirror/lint'; import { Compartment, EditorState } from '@codemirror/state'; import { type ViewUpdate } from '@codemirror/view'; - import type { SyntaxNode } from '@lezer/common'; + import type { SyntaxNode, Tree } from '@lezer/common'; import type { ChannelDictionary, CommandDictionary, ParameterDictionary } from '@nasa-jpl/aerie-ampcs'; import ChevronDownIcon from '@nasa-jpl/stellar/icons/chevron_down.svg?component'; import CollapseIcon from 'bootstrap-icons/icons/arrow-bar-down.svg?component'; @@ -102,6 +102,7 @@ let menu: Menu; let outputFormats: IOutputFormat[]; let selectedNode: SyntaxNode | null; + let currentTree: Tree; let commandInfoMapper: CommandInfoMapper = new SeqNCommandInfoMapper(); let selectedOutputFormat: IOutputFormat | undefined; let toggleSeqJsonPreview: boolean = false; @@ -226,7 +227,7 @@ } } - $: showOutputs = !isInVmlMode && !!outputFormats.length; + $: showOutputs = !isInVmlMode && outputFormats.length > 0; $: { if (showOutputs) { editorHeights = toggleSeqJsonPreview ? '1fr 3px 1fr' : '1.88fr 3px 80px'; @@ -361,6 +362,7 @@ commandInfoMapper = new SeqNCommandInfoMapper(); } selectedNode = updatedSelectionNode; + currentTree = tree; } } @@ -539,6 +541,7 @@ {#if !!commandDictionary && !!selectedNode} void; export let addDefaultArgs: (commandNode: SyntaxNode, argDefs: FswCommandArgument[]) => void; export let commandInfoMapper: CommandInfoMapper; + export let variablesInScope: string[]; + + let argDef: FswCommandArgument | undefined = undefined; + let enableRepeatAdd: boolean = false; + let isSymbol: boolean = false; + + $: argDef = argInfo.argDef; + + $: { + isSymbol = commandInfoMapper.isArgumentNodeOfVariableType(argInfo.node ?? null); + if (!!argDef && isSymbol) { + argDef = { + arg_type: 'enum', + bit_length: null, + default_value: null, + description: argDef.description, + enum_name: 'variables', + name: argDef.name, + range: variablesInScope, + }; + } + } $: enableRepeatAdd = - argInfo.argDef && - isFswCommandArgumentRepeat(argInfo.argDef) && - argInfo.children && - argInfo.argDef.repeat && - argInfo.children.length < argInfo.argDef.repeat.arguments.length * (argInfo.argDef.repeat.max ?? Infinity); + argDef !== undefined && + isFswCommandArgumentRepeat(argDef) && + argInfo.children !== undefined && + argDef.repeat !== null && + argInfo.children.length < argDef.repeat.arguments.length * (argDef.repeat.max ?? Infinity); function addRepeatTuple() { - const repeatArgs = argInfo.argDef && isFswCommandArgumentRepeat(argInfo.argDef) && argInfo.argDef.repeat?.arguments; + const repeatArgs = argDef && isFswCommandArgumentRepeat(argDef) && argDef.repeat?.arguments; if (argInfo.node && repeatArgs) { addDefaultArgs(argInfo.node, repeatArgs); } @@ -43,7 +67,7 @@
- {#if !argInfo.argDef} + {#if !argDef} {#if argInfo.text}
Unknown Argument
{/if} {:else} - - {#if argInfo.argDef.arg_type === 'enum' && argInfo.node} + {#if argInfo.argDef} + { + if (argInfo.node) { + setInEditor(argInfo.node, val); + } + }} + /> + {/if} + {#if isSymbol && isFswCommandArgumentEnum(argDef)} +
Reference
+ { + if (argInfo.node) { + setInEditor(argInfo.node, val); + } + }} + /> + {:else if isFswCommandArgumentEnum(argDef) && argInfo.node} {#if commandInfoMapper.nodeTypeEnumCompatible(argInfo.node)} { if (argInfo.node) { - setInEditor(argInfo.node, val); + setInEditor(argInfo.node, quoteEscape(val)); } }} /> @@ -81,19 +127,19 @@ Convert to enum type {/if} - {:else if isNumberArg(argInfo.argDef) && commandInfoMapper.nodeTypeNumberCompatible(argInfo.node ?? null)} + {:else if isNumberArg(argDef) && commandInfoMapper.nodeTypeNumberCompatible(argInfo.node ?? null)} { if (argInfo.node) { setInEditor(argInfo.node, val.toString()); } }} /> - {:else if isFswCommandArgumentVarString(argInfo.argDef)} + {:else if isFswCommandArgumentVarString(argDef)} { if (argInfo.node) { @@ -101,9 +147,9 @@ } }} /> - {:else if isFswCommandArgumentBoolean(argInfo.argDef)} + {:else if isFswCommandArgumentBoolean(argDef)} { if (argInfo.node) { @@ -111,10 +157,17 @@ } }} /> - {:else if isFswCommandArgumentRepeat(argInfo.argDef) && !!argInfo.children} + {:else if isFswCommandArgumentRepeat(argDef) && !!argInfo.children} {#each argInfo.children as childArgInfo} {#if childArgInfo.node} - + {/if} {/each} {#if argInfo.children.find(childArgInfo => !childArgInfo.node)} @@ -125,15 +178,15 @@ } }} /> - {:else if !!argInfo.argDef.repeat} + {:else if !!argDef.repeat}
{/if} diff --git a/src/components/sequencing/form/ArgTitle.svelte b/src/components/sequencing/form/ArgTitle.svelte index 1bf4f41264..8bd3cabf33 100644 --- a/src/components/sequencing/form/ArgTitle.svelte +++ b/src/components/sequencing/form/ArgTitle.svelte @@ -3,6 +3,8 @@ -
- {argDef.description} +
+ {#if formattedRange} +
Range
+
{formattedRange}
+ {/if} + + {#if typeInfo} +
Type
+
{typeInfo}
+ {/if} + + {#if argDef.description} +
Description
+
+ {argDef.description} +
+ {/if} + +
Value Type
+ +
+ + diff --git a/src/components/sequencing/form/EnumEditor.svelte b/src/components/sequencing/form/EnumEditor.svelte index 0557b43b67..fdd6a67aa1 100644 --- a/src/components/sequencing/form/EnumEditor.svelte +++ b/src/components/sequencing/form/EnumEditor.svelte @@ -3,14 +3,14 @@