feat(ui/scripts): editor support for self/child/parent accessors
Phases 3+4 of the script-scope rollout. Wires the runtime accessors
landed in efba01d through to Monaco completion, diagnostics, and
hover.
New analyzer surface in ScriptAnalysisService:
String-literal completion contexts (added to TryStringLiteralCompletions):
Attributes["..."] -> SelfAttributes
Children["..."] -> composition names
Children["X"].Attributes["..."] -> child template's attributes
Children["X"].CallScript("...") -> child template's scripts
Parent.Attributes["..."] -> parent template's attributes
Parent.CallScript("...") -> parent template's scripts
Diagnostics:
SCADA006 Attribute "Typo" is not declared on {this template,
child composition 'X', the parent}. (warning)
SCADA007 Composition "Unknown" is not declared on this template.
(warning)
CallShared / CallScript snippet-expansion now routes through the
child / parent shape catalogs when invoked on Children["X"] /
Parent — picking a child script accepts `Sample", ${1:count})`.
Contract additions:
- AttributeShape (Name, Type) record
- CompositionContext (Name, Attributes, Scripts) record
- SelfAttributes / Children / Parent fields on DiagnoseRequest,
CompletionsRequest, HoverRequest, SignatureHelpRequest
ScriptHost (analyzer-side globals) gains stub AttributeBag /
ChildrenBag / CompositionBag types so Roslyn doesn't emit CS0103 on
Attributes / Children / Parent. The stubs are never invoked — only
their signatures are read by the analyzer's compilation pass.
MonacoEditor.razor exposes SelfAttributes / Children / Parent
parameters; GetContext returns them; monaco-init.js forwards all
three on completion / hover / signature-help / diagnostics requests.
TemplateEdit fetches each composition's resolved child template
shape via GetTemplateWithChildrenAsync, and queries GetAllTemplatesAsync
for any single parent that composes the open template. Multi-parent
or no-parent → Parent is suppressed.
11 new xUnit tests on the new completion / diagnostic paths. Total:
149 -> 159.
Browser-verified via curl:
- Children["..."] suggests composition names
- Attributes["..."] suggests attributes with type detail
- Attributes["Typo"] squiggles SCADA006
- Children["Unknown"] squiggles SCADA007
- No spurious CS0103 on the new accessors
Hover, signature help, and inlay hints for the new accessors keep
working because they reuse the same dispatch logic.
This commit is contained in:
@@ -38,7 +38,10 @@
|
||||
// Look up the SCADA context for a model by walking the editors map. Blazor
|
||||
// JS interop serializes records as PascalCase; we normalize to camelCase.
|
||||
async function lookupContext(model) {
|
||||
const empty = { declaredParameters: [], siblingScripts: [], declaredParameterShapes: [] };
|
||||
const empty = {
|
||||
declaredParameters: [], siblingScripts: [], declaredParameterShapes: [],
|
||||
selfAttributes: [], children: [], parent: null
|
||||
};
|
||||
for (const key in editors) {
|
||||
if (editors[key].editor.getModel() === model) {
|
||||
try {
|
||||
@@ -47,7 +50,10 @@
|
||||
return {
|
||||
declaredParameters: got.DeclaredParameters || got.declaredParameters || [],
|
||||
siblingScripts: got.SiblingScripts || got.siblingScripts || [],
|
||||
declaredParameterShapes: got.DeclaredParameterShapes || got.declaredParameterShapes || []
|
||||
declaredParameterShapes: got.DeclaredParameterShapes || got.declaredParameterShapes || [],
|
||||
selfAttributes: got.SelfAttributes || got.selfAttributes || [],
|
||||
children: got.Children || got.children || [],
|
||||
parent: got.Parent || got.parent || null
|
||||
};
|
||||
}
|
||||
} catch (e) { /* fall through */ }
|
||||
@@ -73,7 +79,10 @@
|
||||
line: position.lineNumber,
|
||||
column: position.column,
|
||||
declaredParameters: ctx.declaredParameters,
|
||||
siblingScripts: ctx.siblingScripts
|
||||
siblingScripts: ctx.siblingScripts,
|
||||
selfAttributes: ctx.selfAttributes,
|
||||
children: ctx.children,
|
||||
parent: ctx.parent
|
||||
})
|
||||
});
|
||||
if (!resp.ok) return { suggestions: [] };
|
||||
@@ -141,7 +150,10 @@
|
||||
line: position.lineNumber,
|
||||
column: position.column,
|
||||
siblingScripts: ctx.siblingScripts,
|
||||
declaredParameters: ctx.declaredParameterShapes
|
||||
declaredParameters: ctx.declaredParameterShapes,
|
||||
selfAttributes: ctx.selfAttributes,
|
||||
children: ctx.children,
|
||||
parent: ctx.parent
|
||||
})
|
||||
});
|
||||
if (!resp.ok) return null;
|
||||
@@ -186,6 +198,8 @@
|
||||
code: model.getValue(),
|
||||
siblingScripts: ctx.siblingScripts
|
||||
})
|
||||
// Note: inlay hints don't yet read children/parent shapes
|
||||
// because they only label CallShared/CallScript args today.
|
||||
});
|
||||
if (!resp.ok) return { hints: [], dispose: function () {} };
|
||||
const data = await resp.json();
|
||||
@@ -219,7 +233,9 @@
|
||||
codeText: model.getValue(),
|
||||
line: position.lineNumber,
|
||||
column: position.column,
|
||||
siblingScripts: ctx.siblingScripts
|
||||
siblingScripts: ctx.siblingScripts,
|
||||
children: ctx.children,
|
||||
parent: ctx.parent
|
||||
})
|
||||
});
|
||||
if (!resp.ok) return null;
|
||||
|
||||
Reference in New Issue
Block a user