@invinite-org/chartlang-language-service 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/README.md +7 -0
- package/dist/_lib/collectCompletions.d.ts +1 -1
- package/dist/_lib/collectCompletions.d.ts.map +1 -1
- package/dist/_lib/collectCompletions.js +20 -1
- package/dist/_lib/collectCompletions.js.map +1 -1
- package/dist/_lib/isInsideOutputStringLiteral.d.ts +14 -0
- package/dist/_lib/isInsideOutputStringLiteral.d.ts.map +1 -0
- package/dist/_lib/isInsideOutputStringLiteral.js +44 -0
- package/dist/_lib/isInsideOutputStringLiteral.js.map +1 -0
- package/dist/_lib/isInsideWithInputsKey.d.ts +15 -0
- package/dist/_lib/isInsideWithInputsKey.d.ts.map +1 -0
- package/dist/_lib/isInsideWithInputsKey.js +64 -0
- package/dist/_lib/isInsideWithInputsKey.js.map +1 -0
- package/dist/_lib/resolveDepAccessor.d.ts +77 -0
- package/dist/_lib/resolveDepAccessor.d.ts.map +1 -0
- package/dist/_lib/resolveDepAccessor.js +307 -0
- package/dist/_lib/resolveDepAccessor.js.map +1 -0
- package/dist/createLanguageService.d.ts.map +1 -1
- package/dist/createLanguageService.js +15 -11
- package/dist/createLanguageService.js.map +1 -1
- package/dist/hoverRegistry.generated.d.ts.map +1 -1
- package/dist/hoverRegistry.generated.js +104 -5
- package/dist/hoverRegistry.generated.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,70 @@
|
|
|
1
1
|
# @invinite-org/chartlang-language-service
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2123181: Language service understands indicator-composition hovers, output-name
|
|
8
|
+
- override-key completions, and surfaces the new `dep-*` diagnostics
|
|
9
|
+
inline. Hover on `<binding>.output(...)` lists the producer's titled
|
|
10
|
+
outputs; hover on `<binding>.withInputs({...})` lists the producer's
|
|
11
|
+
input schema with kinds + defaults. Completion fires for output titles
|
|
12
|
+
inside `<binding>.output("|")` and for override keys inside
|
|
13
|
+
`<binding>.withInputs({ |})`. Best-effort go-to-definition for
|
|
14
|
+
`.output("title")` navigates to the producer's matching `plot(value,
|
|
15
|
+
{ title })` call when the producer is a same-file `defineIndicator`;
|
|
16
|
+
cross-file and unresolvable cases fall back to `null`. Editor: no
|
|
17
|
+
public API change — new behaviour flows through the existing
|
|
18
|
+
`completionExtension` / `hoverExtension` / `linterExtension` wiring.
|
|
19
|
+
- 2123181: Indicator composition (Phase 7 closeout): one chartlang indicator can
|
|
20
|
+
read another indicator's titled plot output as a typed `Series<number>`.
|
|
21
|
+
|
|
22
|
+
- Compose via local `const` binding plus `<binding>.output("title")` —
|
|
23
|
+
no new public API beyond the chainable `.output` / `.withInputs`
|
|
24
|
+
accessors on `CompiledScriptObject`.
|
|
25
|
+
- A single `.chart.ts` MAY declare a default export plus any number of
|
|
26
|
+
named exports plus any number of private `const` deps. Export form
|
|
27
|
+
determines render policy: drawn exports render with the
|
|
28
|
+
`export:<exportName>/` slot-id prefix; private `const` deps are data
|
|
29
|
+
feeds only and their visuals are dropped.
|
|
30
|
+
- Cross-file `import baseTrend from "./base-trend.chart"` resolves
|
|
31
|
+
recursively; shared producers inline exactly once per consumer.
|
|
32
|
+
- Additive within `apiVersion: 1.x`. The 172-entry
|
|
33
|
+
`STATEFUL_PRIMITIVES` set is unchanged. `DiagnosticCode` widens to 32
|
|
34
|
+
with the new `dep-*` codes (`dep-error`, `dep-cycle`,
|
|
35
|
+
`dep-unknown-output`, `dep-invalid-input-override`, `dep-dynamic`,
|
|
36
|
+
`dep-output-not-titled`).
|
|
37
|
+
- Five conformance scenarios in `@invinite-org/chartlang-conformance`
|
|
38
|
+
pin the runtime contract end-to-end (`dep-private-single-file`,
|
|
39
|
+
`dep-multi-export`, `dep-cross-file`, `dep-diamond`,
|
|
40
|
+
`dep-error-halts-parent`). `Scenario.additionalSources` lets
|
|
41
|
+
cross-file scenarios ship producer + consumer side-by-side.
|
|
42
|
+
- Two new example scripts in `examples/scripts/`:
|
|
43
|
+
`base-trend.chart.ts` (producer) + `trend-confirmation.chart.ts`
|
|
44
|
+
(multi-export consumer). React-demo gains a fifth catalogue entry
|
|
45
|
+
exercising the feature end-to-end in the browser.
|
|
46
|
+
- Docs: `docs/language/indicator-composition.md` narrative guide,
|
|
47
|
+
`docs/spec/manifest.md` + `docs/spec/semantics.md` +
|
|
48
|
+
`docs/spec/versioning.md` updates, five new glossary entries.
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- Updated dependencies [d6d1a1f]
|
|
53
|
+
- Updated dependencies [f0c8eb8]
|
|
54
|
+
- Updated dependencies [f0c8eb8]
|
|
55
|
+
- Updated dependencies [2123181]
|
|
56
|
+
- Updated dependencies [2123181]
|
|
57
|
+
- Updated dependencies [2123181]
|
|
58
|
+
- Updated dependencies [2123181]
|
|
59
|
+
- Updated dependencies [2123181]
|
|
60
|
+
- Updated dependencies [4d77f4d]
|
|
61
|
+
- Updated dependencies [4d77f4d]
|
|
62
|
+
- Updated dependencies [3b4952d]
|
|
63
|
+
- Updated dependencies [0427459]
|
|
64
|
+
- @invinite-org/chartlang-core@1.1.0
|
|
65
|
+
- @invinite-org/chartlang-compiler@1.1.0
|
|
66
|
+
- @invinite-org/chartlang-adapter-kit@1.2.0
|
|
67
|
+
|
|
3
68
|
## 1.1.0
|
|
4
69
|
|
|
5
70
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -24,6 +24,13 @@ pnpm add @invinite-org/chartlang-language-service
|
|
|
24
24
|
| `getAvailableIntervals()` | Reads intervals from target capabilities. |
|
|
25
25
|
| `HOVER_REGISTRY` | Checked-in generated hover-doc table. |
|
|
26
26
|
|
|
27
|
+
Dep-aware surfaces (Phase 0.7 indicator composition):
|
|
28
|
+
hovers + completions for `<binding>.output(...)` and
|
|
29
|
+
`<binding>.withInputs({...})` resolve same-file producer titles and
|
|
30
|
+
input schemas. The new `dep-*` compile diagnostics surface inline via
|
|
31
|
+
`compileToDiagnostics`. Go-to-definition on `.output("title")` jumps
|
|
32
|
+
to the producer's matching `plot(value, { title })` call.
|
|
33
|
+
|
|
27
34
|
## Minimum-viable API call
|
|
28
35
|
|
|
29
36
|
```ts
|
|
@@ -9,5 +9,5 @@ import type { CompletionItem } from "../types.js";
|
|
|
9
9
|
* const items = collectCompletions("const length = 20;", 5, {});
|
|
10
10
|
* void items;
|
|
11
11
|
*/
|
|
12
|
-
export declare function collectCompletions(source: string,
|
|
12
|
+
export declare function collectCompletions(source: string, offset: number, registry: Readonly<Record<string, HoverRegistryEntry>>): ReadonlyArray<CompletionItem>;
|
|
13
13
|
//# sourceMappingURL=collectCompletions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectCompletions.d.ts","sourceRoot":"","sources":["../../src/_lib/collectCompletions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"collectCompletions.d.ts","sourceRoot":"","sources":["../../src/_lib/collectCompletions.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAMlD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,GACvD,aAAa,CAAC,cAAc,CAAC,CAsC/B"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
2
|
// See the LICENSE file in the repo root for full license text.
|
|
3
3
|
import ts from "typescript";
|
|
4
|
+
import { isInsideOutputStringLiteral } from "./isInsideOutputStringLiteral.js";
|
|
5
|
+
import { isInsideWithInputsKey } from "./isInsideWithInputsKey.js";
|
|
6
|
+
import { resolveDepInputsFor, resolveDepOutputsFor } from "./resolveDepAccessor.js";
|
|
4
7
|
import { toHoverDoc } from "./toHoverDoc.js";
|
|
5
8
|
/**
|
|
6
9
|
* Collect registry and source-local completion items for an offset.
|
|
@@ -11,7 +14,23 @@ import { toHoverDoc } from "./toHoverDoc.js";
|
|
|
11
14
|
* const items = collectCompletions("const length = 20;", 5, {});
|
|
12
15
|
* void items;
|
|
13
16
|
*/
|
|
14
|
-
export function collectCompletions(source,
|
|
17
|
+
export function collectCompletions(source, offset, registry) {
|
|
18
|
+
if (isInsideOutputStringLiteral(source, offset)) {
|
|
19
|
+
return Object.freeze(resolveDepOutputsFor(source, offset).map((title) => Object.freeze({
|
|
20
|
+
label: title,
|
|
21
|
+
kind: "property",
|
|
22
|
+
insertText: title,
|
|
23
|
+
detail: "Series<number> output",
|
|
24
|
+
})));
|
|
25
|
+
}
|
|
26
|
+
if (isInsideWithInputsKey(source, offset)) {
|
|
27
|
+
return Object.freeze(resolveDepInputsFor(source, offset).map((entry) => Object.freeze({
|
|
28
|
+
label: entry.name,
|
|
29
|
+
kind: "property",
|
|
30
|
+
insertText: entry.name,
|
|
31
|
+
detail: `${entry.kind} (default: ${entry.defaultText})`,
|
|
32
|
+
})));
|
|
33
|
+
}
|
|
15
34
|
const registryItems = Object.values(registry).map(registryCompletion);
|
|
16
35
|
const localItems = collectLocalIdentifiers(source).map((label) => Object.freeze({
|
|
17
36
|
label,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collectCompletions.js","sourceRoot":"","sources":["../../src/_lib/collectCompletions.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EAAE,MAAM,YAAY,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAC9B,MAAc,EACd,
|
|
1
|
+
{"version":3,"file":"collectCompletions.js","sourceRoot":"","sources":["../../src/_lib/collectCompletions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return `true` when an offset lands inside the string-literal argument
|
|
3
|
+
* of a `<binding>.output("...")` call. The binding name itself is not
|
|
4
|
+
* validated here — the resolver inspects bindings when collecting
|
|
5
|
+
* completions or hovers.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.7
|
|
8
|
+
* @stable
|
|
9
|
+
* @example
|
|
10
|
+
* const inside = isInsideOutputStringLiteral('baseTrend.output("line")', 19);
|
|
11
|
+
* void inside;
|
|
12
|
+
*/
|
|
13
|
+
export declare function isInsideOutputStringLiteral(source: string, offset: number): boolean;
|
|
14
|
+
//# sourceMappingURL=isInsideOutputStringLiteral.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isInsideOutputStringLiteral.d.ts","sourceRoot":"","sources":["../../src/_lib/isInsideOutputStringLiteral.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAkBnF"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
/**
|
|
5
|
+
* Return `true` when an offset lands inside the string-literal argument
|
|
6
|
+
* of a `<binding>.output("...")` call. The binding name itself is not
|
|
7
|
+
* validated here — the resolver inspects bindings when collecting
|
|
8
|
+
* completions or hovers.
|
|
9
|
+
*
|
|
10
|
+
* @since 0.7
|
|
11
|
+
* @stable
|
|
12
|
+
* @example
|
|
13
|
+
* const inside = isInsideOutputStringLiteral('baseTrend.output("line")', 19);
|
|
14
|
+
* void inside;
|
|
15
|
+
*/
|
|
16
|
+
export function isInsideOutputStringLiteral(source, offset) {
|
|
17
|
+
const sourceFile = ts.createSourceFile("script.chart.ts", source, ts.ScriptTarget.Latest, true);
|
|
18
|
+
let matched = false;
|
|
19
|
+
const visit = (node) => {
|
|
20
|
+
if (matched)
|
|
21
|
+
return;
|
|
22
|
+
if (ts.isStringLiteral(node) &&
|
|
23
|
+
offset > node.getStart(sourceFile) &&
|
|
24
|
+
offset < node.getEnd()) {
|
|
25
|
+
matched = isOutputCallArgument(node);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
ts.forEachChild(node, visit);
|
|
29
|
+
};
|
|
30
|
+
visit(sourceFile);
|
|
31
|
+
return matched;
|
|
32
|
+
}
|
|
33
|
+
function isOutputCallArgument(node) {
|
|
34
|
+
const parent = node.parent;
|
|
35
|
+
if (!ts.isCallExpression(parent))
|
|
36
|
+
return false;
|
|
37
|
+
if (parent.arguments[0] !== node)
|
|
38
|
+
return false;
|
|
39
|
+
const callee = parent.expression;
|
|
40
|
+
if (!ts.isPropertyAccessExpression(callee))
|
|
41
|
+
return false;
|
|
42
|
+
return callee.name.text === "output";
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=isInsideOutputStringLiteral.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isInsideOutputStringLiteral.js","sourceRoot":"","sources":["../../src/_lib/isInsideOutputStringLiteral.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B,CAAC,MAAc,EAAE,MAAc;IACtE,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChG,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QAClC,IAAI,OAAO;YAAE,OAAO;QACpB,IACI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;YACxB,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAClC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,EACxB,CAAC;YACC,OAAO,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;YACrC,OAAO;QACX,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC;IACF,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAsB;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return `true` when an offset lands at a **key** position inside the
|
|
3
|
+
* object-literal argument of a `<binding>.withInputs({ ... })` call.
|
|
4
|
+
* Value-position offsets return `false` so completions don't fire when
|
|
5
|
+
* the user is filling in an override's value.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.7
|
|
8
|
+
* @stable
|
|
9
|
+
* @example
|
|
10
|
+
* const source = 'baseTrend.withInputs({ length: 20 })';
|
|
11
|
+
* const atKey = isInsideWithInputsKey(source, source.indexOf("length"));
|
|
12
|
+
* void atKey;
|
|
13
|
+
*/
|
|
14
|
+
export declare function isInsideWithInputsKey(source: string, offset: number): boolean;
|
|
15
|
+
//# sourceMappingURL=isInsideWithInputsKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isInsideWithInputsKey.d.ts","sourceRoot":"","sources":["../../src/_lib/isInsideWithInputsKey.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK7E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Copyright (c) 2026 Invinite. Licensed under the MIT License.
|
|
2
|
+
// See the LICENSE file in the repo root for full license text.
|
|
3
|
+
import ts from "typescript";
|
|
4
|
+
/**
|
|
5
|
+
* Return `true` when an offset lands at a **key** position inside the
|
|
6
|
+
* object-literal argument of a `<binding>.withInputs({ ... })` call.
|
|
7
|
+
* Value-position offsets return `false` so completions don't fire when
|
|
8
|
+
* the user is filling in an override's value.
|
|
9
|
+
*
|
|
10
|
+
* @since 0.7
|
|
11
|
+
* @stable
|
|
12
|
+
* @example
|
|
13
|
+
* const source = 'baseTrend.withInputs({ length: 20 })';
|
|
14
|
+
* const atKey = isInsideWithInputsKey(source, source.indexOf("length"));
|
|
15
|
+
* void atKey;
|
|
16
|
+
*/
|
|
17
|
+
export function isInsideWithInputsKey(source, offset) {
|
|
18
|
+
const sourceFile = ts.createSourceFile("script.chart.ts", source, ts.ScriptTarget.Latest, true);
|
|
19
|
+
const objectLiteral = findEnclosingWithInputsObjectLiteral(sourceFile, offset);
|
|
20
|
+
if (objectLiteral === null)
|
|
21
|
+
return false;
|
|
22
|
+
return !isInsideAnyPropertyValueRange(objectLiteral, sourceFile, offset);
|
|
23
|
+
}
|
|
24
|
+
function findEnclosingWithInputsObjectLiteral(sourceFile, offset) {
|
|
25
|
+
let match = null;
|
|
26
|
+
const visit = (node) => {
|
|
27
|
+
if (match !== null)
|
|
28
|
+
return;
|
|
29
|
+
if (ts.isObjectLiteralExpression(node) &&
|
|
30
|
+
offset > node.getStart(sourceFile) &&
|
|
31
|
+
offset < node.getEnd() &&
|
|
32
|
+
isWithInputsArgument(node)) {
|
|
33
|
+
match = node;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
ts.forEachChild(node, visit);
|
|
37
|
+
};
|
|
38
|
+
visit(sourceFile);
|
|
39
|
+
return match;
|
|
40
|
+
}
|
|
41
|
+
function isWithInputsArgument(node) {
|
|
42
|
+
const parent = node.parent;
|
|
43
|
+
if (!ts.isCallExpression(parent))
|
|
44
|
+
return false;
|
|
45
|
+
if (parent.arguments[0] !== node)
|
|
46
|
+
return false;
|
|
47
|
+
const callee = parent.expression;
|
|
48
|
+
if (!ts.isPropertyAccessExpression(callee))
|
|
49
|
+
return false;
|
|
50
|
+
return callee.name.text === "withInputs";
|
|
51
|
+
}
|
|
52
|
+
function isInsideAnyPropertyValueRange(objectLiteral, sourceFile, offset) {
|
|
53
|
+
for (const property of objectLiteral.properties) {
|
|
54
|
+
if (!ts.isPropertyAssignment(property))
|
|
55
|
+
continue;
|
|
56
|
+
const initializer = property.initializer;
|
|
57
|
+
const start = initializer.getStart(sourceFile);
|
|
58
|
+
const end = initializer.getEnd();
|
|
59
|
+
if (offset >= start && offset <= end)
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=isInsideWithInputsKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isInsideWithInputsKey.js","sourceRoot":"","sources":["../../src/_lib/isInsideWithInputsKey.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,+DAA+D;AAE/D,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,MAAc;IAChE,MAAM,UAAU,GAAG,EAAE,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChG,MAAM,aAAa,GAAG,oCAAoC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC/E,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACzC,OAAO,CAAC,6BAA6B,CAAC,aAAa,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,oCAAoC,CACzC,UAAyB,EACzB,MAAc;IAEd,IAAI,KAAK,GAAsC,IAAI,CAAC;IAEpD,MAAM,KAAK,GAAG,CAAC,IAAa,EAAQ,EAAE;QAClC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO;QAC3B,IACI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;YAClC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAClC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE;YACtB,oBAAoB,CAAC,IAAI,CAAC,EAC5B,CAAC;YACC,KAAK,GAAG,IAAI,CAAC;YACb,OAAO;QACX,CAAC;QACD,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC,CAAC;IACF,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,oBAAoB,CAAC,IAAgC;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACzD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC;AAC7C,CAAC;AAED,SAAS,6BAA6B,CAClC,aAAyC,EACzC,UAAyB,EACzB,MAAc;IAEd,KAAK,MAAM,QAAQ,IAAI,aAAa,CAAC,UAAU,EAAE,CAAC;QAC9C,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;YAAE,SAAS;QACjD,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;QACzC,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;QACjC,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,IAAI,GAAG;YAAE,OAAO,IAAI,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { DefinitionLocation, HoverDoc } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Producer-side input descriptor surfaced by the dep accessor helpers.
|
|
4
|
+
* `kind` is the `input.<kind>(default)` builder name; `defaultText` is
|
|
5
|
+
* the literal default-value text printed verbatim into the completion
|
|
6
|
+
* detail line.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.7
|
|
9
|
+
* @stable
|
|
10
|
+
* @example
|
|
11
|
+
* const d: DepInputDescriptor = {
|
|
12
|
+
* name: "length",
|
|
13
|
+
* kind: "int",
|
|
14
|
+
* defaultText: "20",
|
|
15
|
+
* };
|
|
16
|
+
* void d;
|
|
17
|
+
*/
|
|
18
|
+
export type DepInputDescriptor = Readonly<{
|
|
19
|
+
name: string;
|
|
20
|
+
kind: string;
|
|
21
|
+
defaultText: string;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a hover doc when the offset lands on a `<binding>.output(...)`
|
|
25
|
+
* or `<binding>.withInputs({...})` call site whose binding's initialiser
|
|
26
|
+
* is a same-file `defineIndicator(...)` (optionally chained through
|
|
27
|
+
* `.withInputs(...)`).
|
|
28
|
+
*
|
|
29
|
+
* @since 0.7
|
|
30
|
+
* @stable
|
|
31
|
+
* @example
|
|
32
|
+
* const fn: typeof resolveDepAccessorHover = resolveDepAccessorHover;
|
|
33
|
+
* void fn;
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveDepAccessorHover(source: string, offset: number): HoverDoc | null;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a best-effort go-to-definition target for a
|
|
38
|
+
* `<binding>.output("title")` call. Returns the line / column of the
|
|
39
|
+
* producer's matching `plot(value, { title: "<title>" })` call when
|
|
40
|
+
* resolvable. Returns `null` when the binding is missing, the producer
|
|
41
|
+
* is not a same-file `defineIndicator`, or no matching `plot` call is
|
|
42
|
+
* found.
|
|
43
|
+
*
|
|
44
|
+
* @since 0.7
|
|
45
|
+
* @stable
|
|
46
|
+
* @example
|
|
47
|
+
* const fn: typeof resolveDepAccessorDefinition = resolveDepAccessorDefinition;
|
|
48
|
+
* void fn;
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveDepAccessorDefinition(source: string, offset: number): DefinitionLocation | null;
|
|
51
|
+
/**
|
|
52
|
+
* Collect every producer-side titled output reachable from the binding
|
|
53
|
+
* at the offset's `<binding>.output("|")` call site. Returns `[]` when
|
|
54
|
+
* the binding is missing or the producer is not a same-file
|
|
55
|
+
* `defineIndicator(...)`.
|
|
56
|
+
*
|
|
57
|
+
* @since 0.7
|
|
58
|
+
* @stable
|
|
59
|
+
* @example
|
|
60
|
+
* const titles = resolveDepOutputsFor("baseTrend.output(\"\")", 18);
|
|
61
|
+
* void titles;
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveDepOutputsFor(source: string, offset: number): ReadonlyArray<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Collect every producer-side input descriptor reachable from the
|
|
66
|
+
* binding at the offset's `<binding>.withInputs({ |})` call site.
|
|
67
|
+
* Returns `[]` when the binding is missing or the producer is not a
|
|
68
|
+
* same-file `defineIndicator(...)`.
|
|
69
|
+
*
|
|
70
|
+
* @since 0.7
|
|
71
|
+
* @stable
|
|
72
|
+
* @example
|
|
73
|
+
* const inputs = resolveDepInputsFor("baseTrend.withInputs({ })", 22);
|
|
74
|
+
* void inputs;
|
|
75
|
+
*/
|
|
76
|
+
export declare function resolveDepInputsFor(source: string, offset: number): ReadonlyArray<DepInputDescriptor>;
|
|
77
|
+
//# sourceMappingURL=resolveDepAccessor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolveDepAccessor.d.ts","sourceRoot":"","sources":["../../src/_lib/resolveDepAccessor.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGhE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AAIH;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAQvF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CACxC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACf,kBAAkB,GAAG,IAAI,CAqB3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAO1F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAC/B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACf,aAAa,CAAC,kBAAkB,CAAC,CAOnC"}
|