@alloy-js/core 0.20.0-dev.4 → 0.20.0-dev.7
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/dist/src/binder.d.ts +74 -38
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +235 -173
- package/dist/src/binder.js.map +1 -0
- package/dist/src/code.js +2 -1
- package/dist/src/code.js.map +1 -0
- package/dist/src/components/AppendFile.js +2 -1
- package/dist/src/components/AppendFile.js.map +1 -0
- package/dist/src/components/Block.js +2 -1
- package/dist/src/components/Block.js.map +1 -0
- package/dist/src/components/CopyFile.js +2 -1
- package/dist/src/components/CopyFile.js.map +1 -0
- package/dist/src/components/Declaration.d.ts +2 -2
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +10 -3
- package/dist/src/components/Declaration.js.map +1 -0
- package/dist/src/components/For.js +2 -1
- package/dist/src/components/For.js.map +1 -0
- package/dist/src/components/Indent.js +2 -1
- package/dist/src/components/Indent.js.map +1 -0
- package/dist/src/components/List.js +2 -1
- package/dist/src/components/List.js.map +1 -0
- package/dist/src/components/MemberDeclaration.d.ts +2 -2
- package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
- package/dist/src/components/MemberDeclaration.js +11 -6
- package/dist/src/components/MemberDeclaration.js.map +1 -0
- package/dist/src/components/MemberName.js +2 -1
- package/dist/src/components/MemberName.js.map +1 -0
- package/dist/src/components/MemberScope.d.ts +30 -13
- package/dist/src/components/MemberScope.d.ts.map +1 -1
- package/dist/src/components/MemberScope.js +39 -16
- package/dist/src/components/MemberScope.js.map +1 -0
- package/dist/src/components/Name.js +2 -1
- package/dist/src/components/Name.js.map +1 -0
- package/dist/src/components/Output.d.ts.map +1 -1
- package/dist/src/components/Output.js +4 -6
- package/dist/src/components/Output.js.map +1 -0
- package/dist/src/components/Prose.js +2 -1
- package/dist/src/components/Prose.js.map +1 -0
- package/dist/src/components/ReferenceOrContent.d.ts +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
- package/dist/src/components/ReferenceOrContent.js +2 -1
- package/dist/src/components/ReferenceOrContent.js.map +1 -0
- package/dist/src/components/Scope.d.ts +5 -5
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js +11 -6
- package/dist/src/components/Scope.js.map +1 -0
- package/dist/src/components/Show.js +2 -1
- package/dist/src/components/Show.js.map +1 -0
- package/dist/src/components/SourceDirectory.js +2 -1
- package/dist/src/components/SourceDirectory.js.map +1 -0
- package/dist/src/components/SourceFile.js +2 -1
- package/dist/src/components/SourceFile.js.map +1 -0
- package/dist/src/components/StatementList.js +2 -1
- package/dist/src/components/StatementList.js.map +1 -0
- package/dist/src/components/Switch.js +2 -1
- package/dist/src/components/Switch.js.map +1 -0
- package/dist/src/components/TemplateFile.js +2 -1
- package/dist/src/components/TemplateFile.js.map +1 -0
- package/dist/src/components/UpdateFile.js +2 -1
- package/dist/src/components/UpdateFile.js.map +1 -0
- package/dist/src/components/Wrap.js +2 -1
- package/dist/src/components/Wrap.js.map +1 -0
- package/dist/src/components/index.js +2 -1
- package/dist/src/components/index.js.map +1 -0
- package/dist/src/components/stc/index.js +2 -1
- package/dist/src/components/stc/index.js.map +1 -0
- package/dist/src/components/stc/sti.js +2 -1
- package/dist/src/components/stc/sti.js.map +1 -0
- package/dist/src/context/assignment.js +2 -1
- package/dist/src/context/assignment.js.map +1 -0
- package/dist/src/context/binder.js +2 -1
- package/dist/src/context/binder.js.map +1 -0
- package/dist/src/context/declaration.js +2 -1
- package/dist/src/context/declaration.js.map +1 -0
- package/dist/src/context/index.js +2 -1
- package/dist/src/context/index.js.map +1 -0
- package/dist/src/context/member-declaration.js +2 -1
- package/dist/src/context/member-declaration.js.map +1 -0
- package/dist/src/context/member-scope.d.ts +7 -8
- package/dist/src/context/member-scope.d.ts.map +1 -1
- package/dist/src/context/member-scope.js +7 -6
- package/dist/src/context/member-scope.js.map +1 -0
- package/dist/src/context/name-policy.d.ts.map +1 -1
- package/dist/src/context/name-policy.js +5 -1
- package/dist/src/context/name-policy.js.map +1 -0
- package/dist/src/context/scope.d.ts +1 -0
- package/dist/src/context/scope.d.ts.map +1 -1
- package/dist/src/context/scope.js +9 -1
- package/dist/src/context/scope.js.map +1 -0
- package/dist/src/context/source-directory.js +2 -1
- package/dist/src/context/source-directory.js.map +1 -0
- package/dist/src/context/source-file.js +2 -1
- package/dist/src/context/source-file.js.map +1 -0
- package/dist/src/context.js +2 -1
- package/dist/src/context.js.map +1 -0
- package/dist/src/debug.js +2 -1
- package/dist/src/debug.js.map +1 -0
- package/dist/src/host/alloy-host.browser.js +2 -1
- package/dist/src/host/alloy-host.browser.js.map +1 -0
- package/dist/src/host/alloy-host.js +2 -1
- package/dist/src/host/alloy-host.js.map +1 -0
- package/dist/src/host/interface.js +2 -1
- package/dist/src/host/interface.js.map +1 -0
- package/dist/src/index.browser.js +2 -1
- package/dist/src/index.browser.js.map +1 -0
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -0
- package/dist/src/inspect.browser.d.ts +5 -0
- package/dist/src/inspect.browser.d.ts.map +1 -0
- package/dist/src/inspect.browser.js +6 -0
- package/dist/src/inspect.browser.js.map +1 -0
- package/dist/src/inspect.d.ts +2 -0
- package/dist/src/inspect.d.ts.map +1 -0
- package/dist/src/inspect.js +2 -0
- package/dist/src/inspect.js.map +1 -0
- package/dist/src/jsx-runtime.js +2 -1
- package/dist/src/jsx-runtime.js.map +1 -0
- package/dist/src/name-policy.d.ts +11 -0
- package/dist/src/name-policy.d.ts.map +1 -1
- package/dist/src/name-policy.js +5 -1
- package/dist/src/name-policy.js.map +1 -0
- package/dist/src/props-combinators.js +2 -1
- package/dist/src/props-combinators.js.map +1 -0
- package/dist/src/reactive-union-set.d.ts.map +1 -1
- package/dist/src/reactive-union-set.js +14 -9
- package/dist/src/reactive-union-set.js.map +1 -0
- package/dist/src/reactivity.js +2 -1
- package/dist/src/reactivity.js.map +1 -0
- package/dist/src/refkey.d.ts +39 -3
- package/dist/src/refkey.d.ts.map +1 -1
- package/dist/src/refkey.js +65 -10
- package/dist/src/refkey.js.map +1 -0
- package/dist/src/render.js +2 -1
- package/dist/src/render.js.map +1 -0
- package/dist/src/resource.js +2 -1
- package/dist/src/resource.js.map +1 -0
- package/dist/src/runtime/component.js +2 -1
- package/dist/src/runtime/component.js.map +1 -0
- package/dist/src/runtime/intrinsic.js +2 -1
- package/dist/src/runtime/intrinsic.js.map +1 -0
- package/dist/src/scheduler.js +2 -1
- package/dist/src/scheduler.js.map +1 -0
- package/dist/src/stc.js +2 -1
- package/dist/src/stc.js.map +1 -0
- package/dist/src/sti.js +2 -1
- package/dist/src/sti.js.map +1 -0
- package/dist/src/symbols/basic-scope.d.ts +14 -0
- package/dist/src/symbols/basic-scope.d.ts.map +1 -0
- package/dist/src/symbols/basic-scope.js +21 -0
- package/dist/src/symbols/basic-scope.js.map +1 -0
- package/dist/src/symbols/basic-symbol.d.ts +19 -0
- package/dist/src/symbols/basic-symbol.d.ts.map +1 -0
- package/dist/src/symbols/basic-symbol.js +29 -0
- package/dist/src/symbols/basic-symbol.js.map +1 -0
- package/dist/src/symbols/index.d.ts +3 -1
- package/dist/src/symbols/index.d.ts.map +1 -1
- package/dist/src/symbols/index.js +5 -2
- package/dist/src/symbols/index.js.map +1 -0
- package/dist/src/symbols/output-scope.d.ts +70 -41
- package/dist/src/symbols/output-scope.d.ts.map +1 -1
- package/dist/src/symbols/output-scope.js +100 -131
- package/dist/src/symbols/output-scope.js.map +1 -0
- package/dist/src/symbols/output-space.d.ts +25 -0
- package/dist/src/symbols/output-space.d.ts.map +1 -0
- package/dist/src/symbols/output-space.js +36 -0
- package/dist/src/symbols/output-space.js.map +1 -0
- package/dist/src/symbols/output-symbol.d.ts +213 -37
- package/dist/src/symbols/output-symbol.d.ts.map +1 -1
- package/dist/src/symbols/output-symbol.js +325 -204
- package/dist/src/symbols/output-symbol.js.map +1 -0
- package/dist/src/symbols/symbol-flow.d.ts +1 -1
- package/dist/src/symbols/symbol-flow.d.ts.map +1 -1
- package/dist/src/symbols/symbol-flow.js +24 -8
- package/dist/src/symbols/symbol-flow.js.map +1 -0
- package/dist/src/symbols/symbol-slot.d.ts +27 -9
- package/dist/src/symbols/symbol-slot.d.ts.map +1 -1
- package/dist/src/symbols/symbol-slot.js +22 -5
- package/dist/src/symbols/symbol-slot.js.map +1 -0
- package/dist/src/symbols/symbol-table.d.ts +19 -8
- package/dist/src/symbols/symbol-table.d.ts.map +1 -1
- package/dist/src/symbols/symbol-table.js +67 -17
- package/dist/src/symbols/symbol-table.js.map +1 -0
- package/dist/src/tap.js +2 -1
- package/dist/src/tap.js.map +1 -0
- package/dist/src/tracer.d.ts +15 -3
- package/dist/src/tracer.d.ts.map +1 -1
- package/dist/src/tracer.js +41 -64
- package/dist/src/tracer.js.map +1 -0
- package/dist/src/utils.js +2 -1
- package/dist/src/utils.js.map +1 -0
- package/dist/src/write-output.js +2 -1
- package/dist/src/write-output.js.map +1 -0
- package/dist/test/browser-build.test.js +2 -1
- package/dist/test/browser-build.test.js.map +1 -0
- package/dist/test/children.test.js +2 -1
- package/dist/test/children.test.js.map +1 -0
- package/dist/test/components/append-file.test.js +2 -1
- package/dist/test/components/append-file.test.js.map +1 -0
- package/dist/test/components/block.test.js +2 -1
- package/dist/test/components/block.test.js.map +1 -0
- package/dist/test/components/copy-file.test.js +2 -1
- package/dist/test/components/copy-file.test.js.map +1 -0
- package/dist/test/components/declaration.test.js +11 -15
- package/dist/test/components/declaration.test.js.map +1 -0
- package/dist/test/components/list.test.js +2 -1
- package/dist/test/components/list.test.js.map +1 -0
- package/dist/test/components/prose.test.js +2 -1
- package/dist/test/components/prose.test.js.map +1 -0
- package/dist/test/components/reference-or-content.test.js +4 -3
- package/dist/test/components/reference-or-content.test.js.map +1 -0
- package/dist/test/components/source-file.test.js +2 -1
- package/dist/test/components/source-file.test.js.map +1 -0
- package/dist/test/components/template-file.test.js +2 -1
- package/dist/test/components/template-file.test.js.map +1 -0
- package/dist/test/components/update-file.test.js +2 -1
- package/dist/test/components/update-file.test.js.map +1 -0
- package/dist/test/components/wrap.test.js +2 -1
- package/dist/test/components/wrap.test.js.map +1 -0
- package/dist/test/control-flow/for.test.js +2 -1
- package/dist/test/control-flow/for.test.js.map +1 -0
- package/dist/test/control-flow/match.test.js +2 -1
- package/dist/test/control-flow/match.test.js.map +1 -0
- package/dist/test/control-flow/show.test.js +2 -1
- package/dist/test/control-flow/show.test.js.map +1 -0
- package/dist/test/name-policy.test.js +2 -1
- package/dist/test/name-policy.test.js.map +1 -0
- package/dist/test/props-with-defaults.test.js +2 -1
- package/dist/test/props-with-defaults.test.js.map +1 -0
- package/dist/test/reactive-union-set.test.js +2 -1
- package/dist/test/reactive-union-set.test.js.map +1 -0
- package/dist/test/reactivity/circular-reactives.test.js +2 -1
- package/dist/test/reactivity/circular-reactives.test.js.map +1 -0
- package/dist/test/reactivity/cleanup.test.js +2 -1
- package/dist/test/reactivity/cleanup.test.js.map +1 -0
- package/dist/test/reactivity/memo.test.js +2 -1
- package/dist/test/reactivity/memo.test.js.map +1 -0
- package/dist/test/reactivity/ref-rendering.test.js +2 -1
- package/dist/test/reactivity/ref-rendering.test.js.map +1 -0
- package/dist/test/reactivity/test.test.js +2 -1
- package/dist/test/reactivity/test.test.js.map +1 -0
- package/dist/test/reactivity/untrack.test.js +2 -1
- package/dist/test/reactivity/untrack.test.js.map +1 -0
- package/dist/test/refkey.test.js +2 -1
- package/dist/test/refkey.test.js.map +1 -0
- package/dist/test/rendering/basic.test.js +2 -1
- package/dist/test/rendering/basic.test.js.map +1 -0
- package/dist/test/rendering/code.test.js +2 -1
- package/dist/test/rendering/code.test.js.map +1 -0
- package/dist/test/rendering/formatting.test.js +2 -1
- package/dist/test/rendering/formatting.test.js.map +1 -0
- package/dist/test/rendering/indent.test.js +2 -1
- package/dist/test/rendering/indent.test.js.map +1 -0
- package/dist/test/rendering/memoization.test.js +2 -1
- package/dist/test/rendering/memoization.test.js.map +1 -0
- package/dist/test/rendering/refkeys.test.js +2 -1
- package/dist/test/rendering/refkeys.test.js.map +1 -0
- package/dist/test/split-props.test.js +2 -1
- package/dist/test/split-props.test.js.map +1 -0
- package/dist/test/stc.test.js +2 -1
- package/dist/test/stc.test.js.map +1 -0
- package/dist/test/symbols/output-scope.test.js +34 -198
- package/dist/test/symbols/output-scope.test.js.map +1 -0
- package/dist/test/symbols/output-symbol.test.js +141 -386
- package/dist/test/symbols/output-symbol.test.js.map +1 -0
- package/dist/test/symbols/resolution.test.js +433 -115
- package/dist/test/symbols/resolution.test.js.map +1 -0
- package/dist/test/symbols/symbol-table.test.d.ts +2 -0
- package/dist/test/symbols/symbol-table.test.d.ts.map +1 -0
- package/dist/test/symbols/symbol-table.test.js +15 -0
- package/dist/test/symbols/symbol-table.test.js.map +1 -0
- package/dist/test/symbols/utils.d.ts +10 -24
- package/dist/test/symbols/utils.d.ts.map +1 -1
- package/dist/test/symbols/utils.js +25 -46
- package/dist/test/symbols/utils.js.map +1 -0
- package/dist/test/utils.test.js +2 -1
- package/dist/test/utils.test.js.map +1 -0
- package/dist/testing/extend-expect.js +2 -1
- package/dist/testing/extend-expect.js.map +1 -0
- package/dist/testing/extend-expect.test.js +2 -1
- package/dist/testing/extend-expect.test.js.map +1 -0
- package/dist/testing/index.js +2 -1
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/render.js +2 -1
- package/dist/testing/render.js.map +1 -0
- package/dist/testing/vitest.d.js +2 -1
- package/dist/testing/vitest.d.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -3
- package/src/binder.ts +368 -273
- package/src/components/Declaration.tsx +13 -3
- package/src/components/MemberDeclaration.tsx +15 -8
- package/src/components/MemberScope.tsx +61 -20
- package/src/components/Output.tsx +0 -4
- package/src/components/Scope.tsx +16 -9
- package/src/context/member-scope.ts +10 -10
- package/src/context/name-policy.ts +3 -0
- package/src/context/scope.ts +9 -0
- package/src/inspect.browser.ts +6 -0
- package/src/inspect.ts +1 -0
- package/src/name-policy.ts +14 -0
- package/src/reactive-union-set.ts +14 -8
- package/src/refkey.ts +106 -14
- package/src/symbols/basic-scope.ts +23 -0
- package/src/symbols/basic-symbol.ts +32 -0
- package/src/symbols/index.ts +3 -1
- package/src/symbols/output-scope.ts +131 -170
- package/src/symbols/output-space.ts +49 -0
- package/src/symbols/output-symbol.ts +434 -258
- package/src/symbols/symbol-flow.ts +38 -9
- package/src/symbols/symbol-slot.tsx +46 -8
- package/src/symbols/symbol-table.ts +95 -21
- package/src/tracer.ts +53 -83
- package/temp/api.json +7009 -4461
- package/test/components/declaration.test.tsx +6 -19
- package/test/components/reference-or-content.test.tsx +2 -2
- package/test/symbols/output-scope.test.ts +33 -125
- package/test/symbols/output-symbol.test.ts +128 -348
- package/test/symbols/resolution.test.ts +530 -117
- package/test/symbols/symbol-table.test.ts +15 -0
- package/test/symbols/utils.ts +38 -74
- package/tsdoc.json +4 -0
- package/dist/src/slot.d.ts +0 -15
- package/dist/src/slot.d.ts.map +0 -1
- package/dist/src/slot.js +0 -50
- package/dist/src/symbols/flags.d.ts +0 -70
- package/dist/src/symbols/flags.d.ts.map +0 -1
- package/dist/src/symbols/flags.js +0 -72
- package/dist/test/components/slot.test.d.ts +0 -2
- package/dist/test/components/slot.test.d.ts.map +0 -1
- package/dist/test/components/slot.test.js +0 -134
- package/src/slot.ts +0 -89
- package/src/symbols/flags.ts +0 -82
- package/test/components/slot.test.tsx +0 -174
package/src/binder.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { computed,
|
|
2
|
-
import {
|
|
1
|
+
import { computed, Ref, ShallowRef, shallowRef } from "@vue/reactivity";
|
|
2
|
+
import { useBinder } from "./context/binder.js";
|
|
3
|
+
import { useMemberContext } from "./context/member-scope.js";
|
|
3
4
|
import { useScope } from "./context/scope.js";
|
|
4
|
-
import { effect
|
|
5
|
-
import { refkey, Refkey } from "./refkey.js";
|
|
6
|
-
import { OutputSymbolFlags } from "./symbols/flags.js";
|
|
5
|
+
import { effect } from "./reactivity.js";
|
|
6
|
+
import { isMemberRefkey, refkey, Refkey } from "./refkey.js";
|
|
7
7
|
import { OutputScope } from "./symbols/output-scope.js";
|
|
8
8
|
import { type OutputSymbol } from "./symbols/output-symbol.js";
|
|
9
9
|
import {
|
|
10
10
|
formatRefkeys,
|
|
11
|
-
formatSymbol,
|
|
12
11
|
formatSymbolName,
|
|
13
12
|
trace,
|
|
14
13
|
TracePhase,
|
|
@@ -41,52 +40,18 @@ export interface Binder {
|
|
|
41
40
|
TSymbol extends OutputSymbol = OutputSymbol,
|
|
42
41
|
>(
|
|
43
42
|
currentScope: TScope | undefined,
|
|
44
|
-
currentMemberScope: TScope | undefined,
|
|
45
43
|
key: Refkey,
|
|
44
|
+
options?: ResolveDeclarationByKeyOptions<TScope, TSymbol>,
|
|
46
45
|
): Ref<ResolutionResult<TScope, TSymbol> | undefined>;
|
|
47
46
|
|
|
48
|
-
getSymbolForRefkey<TSymbol extends OutputSymbol>(
|
|
49
|
-
refkey: Refkey,
|
|
50
|
-
): Ref<TSymbol | undefined>;
|
|
51
|
-
|
|
52
47
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* will update.
|
|
48
|
+
* Get a ref to the symbol associated with the given refkey. The value of the
|
|
49
|
+
* ref is undefined if the symbol has not been created yet.
|
|
56
50
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
TSymbol extends OutputSymbol = OutputSymbol,
|
|
60
|
-
>(
|
|
61
|
-
currentScope: TScope | undefined,
|
|
62
|
-
name: string,
|
|
51
|
+
getSymbolForRefkey<TSymbol extends OutputSymbol>(
|
|
52
|
+
refkey: Refkey,
|
|
63
53
|
): Ref<TSymbol | undefined>;
|
|
64
54
|
|
|
65
|
-
findScopeName<TScope extends OutputScope = OutputScope>(
|
|
66
|
-
currentScope: TScope | undefined,
|
|
67
|
-
name: string,
|
|
68
|
-
): Ref<TScope | undefined>;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Resolve a fully qualified name to a symbol. Access a nested scope by name
|
|
72
|
-
* with `::`, a nested static member with `.` and a nested instance member
|
|
73
|
-
* with `#`.
|
|
74
|
-
*
|
|
75
|
-
* Per-language packages may provide their own resolveFQN function that uses
|
|
76
|
-
* syntax more natural to that language.
|
|
77
|
-
*/
|
|
78
|
-
resolveFQN<
|
|
79
|
-
TScope extends OutputScope = OutputScope,
|
|
80
|
-
TSymbol extends OutputSymbol = OutputSymbol,
|
|
81
|
-
>(
|
|
82
|
-
fqn: string,
|
|
83
|
-
): Ref<TSymbol | TScope | undefined>;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* The global scope. This is the root scope for all symbols.
|
|
87
|
-
*/
|
|
88
|
-
globalScope: OutputScope;
|
|
89
|
-
|
|
90
55
|
/**
|
|
91
56
|
* The name conflict resolver to use for this binder.
|
|
92
57
|
*/
|
|
@@ -119,7 +84,7 @@ export interface Binder {
|
|
|
119
84
|
* scope: global scope
|
|
120
85
|
* ├── scope: namespace scope 1
|
|
121
86
|
* │ └── symbol: foo
|
|
122
|
-
* │ └── static
|
|
87
|
+
* │ └── static members
|
|
123
88
|
* │ └── symbol: bar
|
|
124
89
|
* └── scope: namespace scope 2
|
|
125
90
|
* └── (resolve bar from here)
|
|
@@ -139,11 +104,21 @@ export interface ResolutionResult<
|
|
|
139
104
|
TSymbol extends OutputSymbol,
|
|
140
105
|
> {
|
|
141
106
|
/**
|
|
142
|
-
* The symbol
|
|
107
|
+
* The resolved symbol. May be declared in a lexical scope or be a member symbol.
|
|
143
108
|
*/
|
|
144
|
-
|
|
109
|
+
symbol: TSymbol;
|
|
110
|
+
|
|
145
111
|
/**
|
|
146
|
-
*
|
|
112
|
+
* When the symbol is a member symbol, this is the symbol of the lexical
|
|
113
|
+
* declaration which contains this member symbol, either as one of its own
|
|
114
|
+
* member symbols, or as a member of one of its members.
|
|
115
|
+
*
|
|
116
|
+
* When the symbol is a non-member symbol, this is the same as `symbol`.
|
|
117
|
+
*/
|
|
118
|
+
lexicalDeclaration: TSymbol;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The scopes between the common scope and the reference.
|
|
147
122
|
*/
|
|
148
123
|
pathUp: TScope[];
|
|
149
124
|
|
|
@@ -153,21 +128,78 @@ export interface ResolutionResult<
|
|
|
153
128
|
pathDown: TScope[];
|
|
154
129
|
|
|
155
130
|
/**
|
|
156
|
-
* The
|
|
131
|
+
* The scopes from the root to scope of the lexical declaration.
|
|
132
|
+
*/
|
|
133
|
+
fullSymbolPath: TScope[];
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The scopes from the root to the scope of the reference.
|
|
137
|
+
*/
|
|
138
|
+
fullReferencePath: TScope[];
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The lexical scope which contains both the reference and the lexical
|
|
142
|
+
* declaration. Undefined when they do not share a common scope.
|
|
157
143
|
*/
|
|
158
144
|
commonScope: TScope | undefined;
|
|
159
145
|
|
|
160
146
|
/**
|
|
161
147
|
* When resolving a member symbol, this is the path of symbols that lead from
|
|
162
|
-
* the
|
|
148
|
+
* the lexical declaration to the member symbol.
|
|
163
149
|
*/
|
|
164
|
-
memberPath
|
|
150
|
+
memberPath: TSymbol[];
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Describes a member in a member access chain, tracking both the symbol
|
|
155
|
+
* and whether this specific member was accessed via a memberRefkey.
|
|
156
|
+
*/
|
|
157
|
+
export interface MemberDescriptor {
|
|
158
|
+
symbol: OutputSymbol;
|
|
159
|
+
isMemberAccess: boolean;
|
|
165
160
|
}
|
|
166
161
|
|
|
167
162
|
export interface NameConflictResolver {
|
|
168
163
|
(name: string, symbols: OutputSymbol[]): void;
|
|
169
164
|
}
|
|
170
165
|
|
|
166
|
+
/**
|
|
167
|
+
* The context for a member resolution. This is used to properly resolve a
|
|
168
|
+
* member in the MemberResolver.
|
|
169
|
+
*/
|
|
170
|
+
export interface MemberResolutionContext<TScope extends OutputScope> {
|
|
171
|
+
/**
|
|
172
|
+
* The scopes that the member reference occurred in.
|
|
173
|
+
*/
|
|
174
|
+
referencePath: TScope[];
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Whether we are using member access e.g. via `memberRefkey`.
|
|
178
|
+
* This is true when the member was resolved using a memberRefkey,
|
|
179
|
+
* which may carry additional metadata about the member access in the future.
|
|
180
|
+
*/
|
|
181
|
+
isMemberAccess: boolean;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
*
|
|
186
|
+
*/
|
|
187
|
+
export interface MemberResolver<
|
|
188
|
+
TScope extends OutputScope,
|
|
189
|
+
TSymbol extends OutputSymbol,
|
|
190
|
+
> {
|
|
191
|
+
(
|
|
192
|
+
owner: TSymbol,
|
|
193
|
+
member: TSymbol,
|
|
194
|
+
context: MemberResolutionContext<TScope>,
|
|
195
|
+
): void;
|
|
196
|
+
}
|
|
197
|
+
export interface ResolveDeclarationByKeyOptions<
|
|
198
|
+
TScope extends OutputScope,
|
|
199
|
+
TSymbol extends OutputSymbol,
|
|
200
|
+
> {
|
|
201
|
+
memberResolver?: MemberResolver<TScope, TSymbol>;
|
|
202
|
+
}
|
|
171
203
|
export interface BinderOptions {
|
|
172
204
|
nameConflictResolver?: NameConflictResolver;
|
|
173
205
|
}
|
|
@@ -176,21 +208,12 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
176
208
|
const binder: Binder = {
|
|
177
209
|
resolveDeclarationByKey,
|
|
178
210
|
getSymbolForRefkey,
|
|
179
|
-
findSymbolName,
|
|
180
|
-
findScopeName,
|
|
181
|
-
resolveFQN: resolveFQN as any,
|
|
182
|
-
globalScope: undefined as any,
|
|
183
211
|
notifyScopeCreated,
|
|
184
212
|
notifySymbolCreated,
|
|
185
213
|
notifySymbolDeleted,
|
|
186
214
|
nameConflictResolver: options.nameConflictResolver,
|
|
187
215
|
};
|
|
188
216
|
|
|
189
|
-
binder.globalScope = new OutputScope("<global>", {
|
|
190
|
-
binder,
|
|
191
|
-
kind: "global",
|
|
192
|
-
});
|
|
193
|
-
|
|
194
217
|
const knownDeclarations = new Map<Refkey, OutputSymbol>();
|
|
195
218
|
const waitingDeclarations = new Map<Refkey, Ref<OutputSymbol | undefined>>();
|
|
196
219
|
const waitingSymbolNames = new Map<
|
|
@@ -228,75 +251,112 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
228
251
|
}
|
|
229
252
|
}
|
|
230
253
|
|
|
231
|
-
function hasTransientScope(symbol: OutputSymbol) {
|
|
232
|
-
let sym: OutputSymbol | undefined = symbol;
|
|
233
|
-
let transient = false;
|
|
234
|
-
while (sym) {
|
|
235
|
-
if (sym.flags & OutputSymbolFlags.Transient) {
|
|
236
|
-
transient = true;
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
|
-
if (sym.flags & ~OutputSymbolFlags.Member) {
|
|
240
|
-
break;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
sym = sym.scope.owner;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return transient;
|
|
247
|
-
}
|
|
248
254
|
function buildResult<
|
|
249
255
|
TScope extends OutputScope = OutputScope,
|
|
250
256
|
TSymbol extends OutputSymbol = OutputSymbol,
|
|
251
257
|
>(
|
|
252
258
|
currentScope: TScope | undefined,
|
|
253
|
-
currentMemberScope: TScope | undefined,
|
|
254
259
|
targetDeclarationBase: TSymbol,
|
|
255
260
|
): ResolutionResult<TScope, TSymbol> {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
261
|
+
const { memberPath: targetMemberPath, scopeChain: targetChain } =
|
|
262
|
+
scopeAndMemberChain<TScope, TSymbol>(targetDeclarationBase);
|
|
263
|
+
|
|
264
|
+
let targetLexicalDeclaration =
|
|
265
|
+
targetMemberPath && targetMemberPath.length > 0 ?
|
|
266
|
+
(targetMemberPath[0].ownerSymbol! as TSymbol)
|
|
267
|
+
: targetDeclarationBase;
|
|
268
|
+
// when we are resolving from a scope which is a member scope and might have
|
|
269
|
+
// member scope parents, and any symbols in the member path are members of
|
|
270
|
+
// the member scope's owner symbol (i.e., those symbols are in scope where
|
|
271
|
+
// the reference is made), we replace the target member path with an entry
|
|
272
|
+
// on the scope chain.
|
|
273
|
+
|
|
274
|
+
// So, first we find all the owner symbols for any member scopes in scope
|
|
275
|
+
// for the reference.
|
|
276
|
+
const referenceChain = scopeChain(currentScope);
|
|
277
|
+
|
|
278
|
+
const inScopeSymbols = new Map<TSymbol, TScope>();
|
|
279
|
+
for (const scope of referenceChain) {
|
|
280
|
+
if (scope.isMemberScope) {
|
|
281
|
+
inScopeSymbols.set(scope.ownerSymbol! as TSymbol, scope);
|
|
282
|
+
}
|
|
268
283
|
}
|
|
269
284
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
285
|
+
// then if the lexical declaration symbol's members are in scope, remove the
|
|
286
|
+
// symbol from the member path and add its corresponding member scope to the
|
|
287
|
+
// target chain.
|
|
288
|
+
while (
|
|
289
|
+
targetMemberPath.length > 0 &&
|
|
290
|
+
inScopeSymbols.has(targetLexicalDeclaration)
|
|
291
|
+
) {
|
|
292
|
+
targetChain.push(inScopeSymbols.get(targetLexicalDeclaration)!);
|
|
293
|
+
targetLexicalDeclaration = targetMemberPath.shift()!;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Now we replace any scopes in the target chain with corresponding scopes
|
|
297
|
+
// from the reference chain.
|
|
298
|
+
for (const [index, scope] of targetChain.entries()) {
|
|
299
|
+
if (inScopeSymbols.has(scope.ownerSymbol! as TSymbol)) {
|
|
300
|
+
targetChain[index] = inScopeSymbols.get(scope.ownerSymbol! as TSymbol)!;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Next we look for member scopes in the target chain that correspond to
|
|
305
|
+
// member scopes in the reference chain. We splice the reference chain into
|
|
306
|
+
// the target chain at that point. This ensures that we establish the proper
|
|
307
|
+
// common scope and path up/down even if the reference chain has additional
|
|
308
|
+
// scopes above it (e.g. a scope for the current source file).
|
|
309
|
+
const commonMemberContainer = targetChain.findIndex(
|
|
310
|
+
(scope) =>
|
|
311
|
+
scope.isMemberScope && inScopeSymbols.has(scope.ownerSymbol as TSymbol),
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
if (commonMemberContainer > -1) {
|
|
315
|
+
const sourceLocation = referenceChain.findIndex(
|
|
316
|
+
(scope) =>
|
|
317
|
+
scope.isMemberScope &&
|
|
318
|
+
scope.ownerSymbol === targetChain[commonMemberContainer].ownerSymbol,
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
// source location is guaranteed to exist at this point.
|
|
322
|
+
targetChain.splice(
|
|
323
|
+
0,
|
|
324
|
+
commonMemberContainer + 1,
|
|
325
|
+
...referenceChain.slice(0, sourceLocation + 1),
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Now that we have the target chain and scopes, we can determine the common
|
|
330
|
+
// scopes and paths.
|
|
275
331
|
let diffStart = 0;
|
|
276
332
|
while (
|
|
277
333
|
targetChain[diffStart] &&
|
|
278
|
-
|
|
279
|
-
targetChain[diffStart] ===
|
|
334
|
+
referenceChain[diffStart] &&
|
|
335
|
+
targetChain[diffStart] === referenceChain[diffStart]
|
|
280
336
|
) {
|
|
281
337
|
diffStart++;
|
|
282
338
|
}
|
|
283
|
-
|
|
284
|
-
const pathUp = currentChain.slice(diffStart);
|
|
339
|
+
const pathUp = referenceChain.slice(diffStart);
|
|
285
340
|
const pathDown = targetChain.slice(diffStart);
|
|
286
|
-
const commonScope = targetChain[diffStart - 1] ??
|
|
341
|
+
const commonScope = targetChain[diffStart - 1] ?? undefined;
|
|
287
342
|
|
|
288
343
|
return {
|
|
289
344
|
pathUp,
|
|
290
345
|
pathDown,
|
|
291
|
-
memberPath,
|
|
346
|
+
memberPath: targetMemberPath,
|
|
292
347
|
commonScope,
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
348
|
+
symbol: targetDeclarationBase,
|
|
349
|
+
lexicalDeclaration: targetLexicalDeclaration,
|
|
350
|
+
fullSymbolPath: targetChain,
|
|
351
|
+
fullReferencePath: referenceChain,
|
|
297
352
|
};
|
|
298
353
|
}
|
|
299
354
|
|
|
355
|
+
/**
|
|
356
|
+
* Walk from the provided symbol up to the non-member symbol. This constitutes
|
|
357
|
+
* the member path. Then, walk from the first non-member symbol's scope up to
|
|
358
|
+
* the global scope. This constitutes the scope chain.
|
|
359
|
+
*/
|
|
300
360
|
function scopeAndMemberChain<
|
|
301
361
|
TScope extends OutputScope,
|
|
302
362
|
TSymbol extends OutputSymbol,
|
|
@@ -305,15 +365,14 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
305
365
|
memberPath: [] as TSymbol[],
|
|
306
366
|
scopeChain: [] as TScope[],
|
|
307
367
|
};
|
|
308
|
-
|
|
309
368
|
let currentSymbol = symbol;
|
|
310
|
-
while (currentSymbol.flags & OutputSymbolFlags.StaticMember) {
|
|
311
|
-
result.memberPath.unshift(currentSymbol);
|
|
312
|
-
currentSymbol = currentSymbol.scope.owner! as TSymbol;
|
|
313
|
-
}
|
|
314
369
|
|
|
315
|
-
if (
|
|
316
|
-
result.memberPath
|
|
370
|
+
if (currentSymbol.isMemberSymbol) {
|
|
371
|
+
result.memberPath = [];
|
|
372
|
+
while (currentSymbol.isMemberSymbol) {
|
|
373
|
+
result.memberPath.unshift(currentSymbol);
|
|
374
|
+
currentSymbol = currentSymbol.ownerSymbol as TSymbol;
|
|
375
|
+
}
|
|
317
376
|
}
|
|
318
377
|
|
|
319
378
|
const startScope = currentSymbol.scope as TScope;
|
|
@@ -339,7 +398,30 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
339
398
|
return waitingDeclarations.get(refkey)! as ShallowRef<TSymbol>;
|
|
340
399
|
}
|
|
341
400
|
|
|
342
|
-
|
|
401
|
+
let symbolRef: ShallowRef<TSymbol | undefined>;
|
|
402
|
+
|
|
403
|
+
if (isMemberRefkey(refkey)) {
|
|
404
|
+
const baseSymbolRef: ShallowRef<TSymbol | undefined> =
|
|
405
|
+
getSymbolForRefkey<TSymbol>(refkey.base);
|
|
406
|
+
const memberSymbolRef: ShallowRef<TSymbol | undefined> =
|
|
407
|
+
getSymbolForRefkey<TSymbol>(refkey.member);
|
|
408
|
+
|
|
409
|
+
symbolRef = computed(() => {
|
|
410
|
+
// even though we don't necessarily need the base symbol to be available
|
|
411
|
+
// yet (the member symbol might already be declared on a type), we wait
|
|
412
|
+
// to resolve the member refkey until the base symbol is available.
|
|
413
|
+
const baseSymbol = baseSymbolRef.value;
|
|
414
|
+
const memberSymbol = memberSymbolRef.value;
|
|
415
|
+
if (!baseSymbol || !memberSymbol) {
|
|
416
|
+
return undefined;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return memberSymbol;
|
|
420
|
+
}) as ShallowRef<TSymbol | undefined>;
|
|
421
|
+
} else {
|
|
422
|
+
symbolRef = shallowRef<TSymbol | undefined>();
|
|
423
|
+
}
|
|
424
|
+
|
|
343
425
|
waitingDeclarations.set(refkey, symbolRef);
|
|
344
426
|
if (knownDeclarations.has(refkey)) {
|
|
345
427
|
symbolRef.value = knownDeclarations.get(refkey) as TSymbol;
|
|
@@ -347,15 +429,23 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
347
429
|
return symbolRef;
|
|
348
430
|
}
|
|
349
431
|
|
|
432
|
+
/**
|
|
433
|
+
* There are two ways to reference a member symbol - directly via its refkey,
|
|
434
|
+
* and via a member refkey. In the former case, we just find the member
|
|
435
|
+
* symbol, and then compute its path directly from there. In hte latter case,
|
|
436
|
+
* we need to find the base of the member expression, and then add the members
|
|
437
|
+
* from the (possibly nested) member refkey to result.
|
|
438
|
+
*/
|
|
350
439
|
function resolveDeclarationByKey<
|
|
351
440
|
TScope extends OutputScope = OutputScope,
|
|
352
441
|
TSymbol extends OutputSymbol = OutputSymbol,
|
|
353
442
|
>(
|
|
354
443
|
currentScope: TScope | undefined,
|
|
355
|
-
currentMemberScope: TScope | undefined,
|
|
356
444
|
refkey: Refkey,
|
|
445
|
+
options: ResolveDeclarationByKeyOptions<TScope, TSymbol> = {},
|
|
357
446
|
): ShallowRef<ResolutionResult<TScope, TSymbol> | undefined> {
|
|
358
447
|
const resolvedSymbol = getSymbolForRefkey(refkey);
|
|
448
|
+
|
|
359
449
|
return computed(() => {
|
|
360
450
|
trace(
|
|
361
451
|
TracePhase.resolve.pending,
|
|
@@ -374,33 +464,147 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
374
464
|
() =>
|
|
375
465
|
`${formatRefkeys(refkey)} resolved to ${formatSymbolName(symbol)}.`,
|
|
376
466
|
);
|
|
377
|
-
if (
|
|
467
|
+
if (symbol.isTransient) {
|
|
378
468
|
trace(
|
|
379
469
|
TracePhase.resolve.failure,
|
|
380
|
-
() => `Symbol ${formatSymbolName(symbol)}
|
|
470
|
+
() => `Symbol ${formatSymbolName(symbol)} is transient.`,
|
|
381
471
|
);
|
|
382
472
|
return undefined;
|
|
383
473
|
}
|
|
384
474
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
(
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
475
|
+
const chain = scopeChain(symbol.scope);
|
|
476
|
+
if (chain.some((scope) => scope.isTransient)) {
|
|
477
|
+
trace(
|
|
478
|
+
TracePhase.resolve.failure,
|
|
479
|
+
() => `Symbol ${formatSymbolName(symbol)} is in a transient scope.`,
|
|
480
|
+
);
|
|
481
|
+
return undefined;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
let result: ResolutionResult<TScope, TSymbol>;
|
|
485
|
+
let memberDescriptorsFromRefkey: MemberDescriptor[];
|
|
486
|
+
|
|
487
|
+
if (isMemberRefkey(refkey)) {
|
|
488
|
+
memberDescriptorsFromRefkey = getMemberPathFromRefkey(refkey);
|
|
489
|
+
|
|
490
|
+
result = buildResult(
|
|
491
|
+
currentScope,
|
|
492
|
+
memberDescriptorsFromRefkey[0].symbol as TSymbol,
|
|
493
|
+
);
|
|
494
|
+
} else {
|
|
495
|
+
memberDescriptorsFromRefkey = [];
|
|
496
|
+
result = buildResult(currentScope, symbol);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// When we have member descriptors, this first entry is already part of the result due to passing it
|
|
500
|
+
// to buildResult above, so we don't need it here.
|
|
501
|
+
const newMemberPathDescriptors = memberDescriptorsFromRefkey.slice(1);
|
|
502
|
+
const allDescriptors = [
|
|
503
|
+
...result.memberPath.map((s) => ({ symbol: s, isMemberAccess: false })),
|
|
504
|
+
...newMemberPathDescriptors,
|
|
505
|
+
];
|
|
506
|
+
|
|
507
|
+
// update the member path and resolved symbol from our member descriptors
|
|
508
|
+
// (if we have them)
|
|
509
|
+
if (memberDescriptorsFromRefkey.length > 0) {
|
|
510
|
+
for (const descriptor of newMemberPathDescriptors) {
|
|
511
|
+
result.memberPath.push(descriptor.symbol as TSymbol);
|
|
512
|
+
}
|
|
513
|
+
result.symbol = memberDescriptorsFromRefkey.at(-1)!.symbol as TSymbol;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// a subcomputed here ensures we don't lose the progress above When
|
|
517
|
+
// we fail to resolve because a type isn't available yet.
|
|
518
|
+
return computed(() => {
|
|
519
|
+
// resolve each member in the member path
|
|
520
|
+
let currentBase = result.lexicalDeclaration;
|
|
521
|
+
|
|
522
|
+
for (const descriptor of allDescriptors) {
|
|
523
|
+
const member = descriptor.symbol as TSymbol;
|
|
524
|
+
if (currentBase.isTyped && !currentBase.hasTypeSymbol) {
|
|
525
|
+
trace(
|
|
526
|
+
TracePhase.resolve.pending,
|
|
527
|
+
() =>
|
|
528
|
+
`${formatRefkeys(refkey)} needs type information from a parent type.`,
|
|
529
|
+
);
|
|
530
|
+
// waiting for type
|
|
531
|
+
return undefined;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
resolveMember(currentBase, member, options.memberResolver, {
|
|
535
|
+
referencePath: result.fullReferencePath,
|
|
536
|
+
isMemberAccess: descriptor.isMemberAccess,
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
currentBase = member;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
trace(
|
|
543
|
+
TracePhase.resolve.success,
|
|
544
|
+
() =>
|
|
545
|
+
`${formatRefkeys(refkey)} successfully resolved to ${formatSymbolName(symbol)}.`,
|
|
546
|
+
);
|
|
547
|
+
return result;
|
|
548
|
+
}).value;
|
|
391
549
|
});
|
|
392
550
|
}
|
|
393
551
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
552
|
+
/**
|
|
553
|
+
* Extracts member descriptors from a refkey, tracking which members
|
|
554
|
+
* were accessed via memberRefkey for proper member resolution context.
|
|
555
|
+
*/
|
|
556
|
+
function getMemberPathFromRefkey(refkey: Refkey): MemberDescriptor[] {
|
|
557
|
+
if (isMemberRefkey(refkey)) {
|
|
558
|
+
return [
|
|
559
|
+
...getMemberPathFromRefkey(refkey.base),
|
|
560
|
+
{
|
|
561
|
+
symbol: getSymbolForRefkey(refkey.member).value!,
|
|
562
|
+
isMemberAccess: true,
|
|
563
|
+
},
|
|
564
|
+
];
|
|
398
565
|
}
|
|
566
|
+
|
|
567
|
+
return [
|
|
568
|
+
{
|
|
569
|
+
symbol: getSymbolForRefkey(refkey).value!,
|
|
570
|
+
isMemberAccess: false,
|
|
571
|
+
},
|
|
572
|
+
];
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
function resolveMember(
|
|
576
|
+
base: OutputSymbol,
|
|
577
|
+
member: OutputSymbol,
|
|
578
|
+
memberResolver: MemberResolver<any, any> | undefined,
|
|
579
|
+
context: MemberResolutionContext<any>,
|
|
580
|
+
) {
|
|
581
|
+
if (memberResolver) {
|
|
582
|
+
memberResolver(base, member, context);
|
|
583
|
+
} else {
|
|
584
|
+
// default member resolution
|
|
585
|
+
if (!member.isMemberSymbol) {
|
|
586
|
+
throw new Error(`${formatSymbolName(member)} is not a member symbol.`);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
const memberOwner = base.hasTypeSymbol ? base.type : base.dealias();
|
|
590
|
+
if (member.ownerSymbol !== memberOwner) {
|
|
591
|
+
throw new Error(
|
|
592
|
+
`${formatSymbolName(
|
|
593
|
+
member,
|
|
594
|
+
)} is not a member of ${formatSymbolName(base)}.`,
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function notifySymbolCreated(symbol: OutputSymbol): void {
|
|
399
601
|
effect<Refkey[]>((oldRefkeys) => {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
602
|
+
if (symbol.refkeys) {
|
|
603
|
+
trace(
|
|
604
|
+
TracePhase.resolve.pending,
|
|
605
|
+
() => `Notifying resolutions for ${formatRefkeys(symbol.refkeys)}.`,
|
|
606
|
+
);
|
|
607
|
+
}
|
|
404
608
|
|
|
405
609
|
if (oldRefkeys) {
|
|
406
610
|
for (const refkey of oldRefkeys) {
|
|
@@ -425,8 +629,13 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
425
629
|
signal.value = symbol;
|
|
426
630
|
}
|
|
427
631
|
|
|
632
|
+
const scope = symbol.scope;
|
|
633
|
+
if (!scope) {
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
|
|
428
637
|
// notify those waiting for this symbol name
|
|
429
|
-
const waitingScope = waitingSymbolNames.get(
|
|
638
|
+
const waitingScope = waitingSymbolNames.get(scope);
|
|
430
639
|
if (waitingScope) {
|
|
431
640
|
const waitingName = waitingScope.get(symbol.name);
|
|
432
641
|
if (waitingName) {
|
|
@@ -438,113 +647,6 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
438
647
|
return [...symbol.refkeys];
|
|
439
648
|
});
|
|
440
649
|
}
|
|
441
|
-
|
|
442
|
-
function findSymbolName<TSymbol extends OutputSymbol = OutputSymbol>(
|
|
443
|
-
scope: OutputScope | undefined,
|
|
444
|
-
name: string,
|
|
445
|
-
): ShallowRef<TSymbol | undefined> {
|
|
446
|
-
return untrack(() => {
|
|
447
|
-
scope ??= binder.globalScope;
|
|
448
|
-
for (const sym of scope.symbols) {
|
|
449
|
-
if (sym.name === name) {
|
|
450
|
-
return shallowRef(sym) as Ref<TSymbol>;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
const symRef = shallowRef<OutputSymbol | undefined>(undefined);
|
|
455
|
-
if (!waitingSymbolNames.has(scope)) {
|
|
456
|
-
waitingSymbolNames.set(scope, new Map());
|
|
457
|
-
}
|
|
458
|
-
const waiting = waitingSymbolNames.get(scope)!;
|
|
459
|
-
waiting.set(name, symRef);
|
|
460
|
-
return symRef as Ref<TSymbol | undefined>;
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
function findScopeName<TScope extends OutputScope = OutputScope>(
|
|
465
|
-
scope: OutputScope | undefined,
|
|
466
|
-
name: string,
|
|
467
|
-
): ShallowRef<TScope | undefined> {
|
|
468
|
-
return untrack(() => {
|
|
469
|
-
scope ??= binder.globalScope;
|
|
470
|
-
for (const child of scope.children) {
|
|
471
|
-
if (child.name === name) {
|
|
472
|
-
return shallowRef(child) as Ref<TScope>;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const scopeRef = shallowRef<OutputScope | undefined>(undefined);
|
|
477
|
-
if (!waitingScopeNames.has(scope)) {
|
|
478
|
-
waitingScopeNames.set(scope, new Map());
|
|
479
|
-
}
|
|
480
|
-
const waiting = waitingScopeNames.get(scope)!;
|
|
481
|
-
waiting.set(name, scopeRef);
|
|
482
|
-
|
|
483
|
-
return scopeRef as Ref<TScope | undefined>;
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
function findScopeOrSymbolName(scope: OutputScope, name: string) {
|
|
488
|
-
return untrack(() => {
|
|
489
|
-
return computed(() => {
|
|
490
|
-
return (
|
|
491
|
-
findSymbolName(scope, name).value ?? findScopeName(scope, name).value
|
|
492
|
-
);
|
|
493
|
-
});
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
function resolveFQN(
|
|
498
|
-
fqn: string,
|
|
499
|
-
): Ref<OutputScope | OutputSymbol | undefined> {
|
|
500
|
-
const parts = fqn.match(/[^.#]+|[.#]/g);
|
|
501
|
-
if (!parts) return ref(undefined);
|
|
502
|
-
if (parts.length === 0) return ref(undefined);
|
|
503
|
-
|
|
504
|
-
parts.unshift(".");
|
|
505
|
-
|
|
506
|
-
return computed(() => {
|
|
507
|
-
let base: OutputScope | OutputSymbol | undefined = binder.globalScope;
|
|
508
|
-
|
|
509
|
-
for (let i = 0; i < parts.length; i += 2) {
|
|
510
|
-
if (base === undefined) {
|
|
511
|
-
return;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
const op = parts[i];
|
|
515
|
-
const name = parts[i + 1];
|
|
516
|
-
|
|
517
|
-
if (op === ".") {
|
|
518
|
-
if ("originalName" in base) {
|
|
519
|
-
if (!base.staticMemberScope) {
|
|
520
|
-
return undefined;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
base = findSymbolName(
|
|
524
|
-
(base as OutputSymbol).staticMemberScope,
|
|
525
|
-
name,
|
|
526
|
-
).value;
|
|
527
|
-
} else {
|
|
528
|
-
base = findScopeOrSymbolName(base, name).value;
|
|
529
|
-
}
|
|
530
|
-
} else if (op === "#") {
|
|
531
|
-
if ("originalName" in base) {
|
|
532
|
-
if (!base.instanceMemberScope) {
|
|
533
|
-
return undefined;
|
|
534
|
-
}
|
|
535
|
-
base = findSymbolName(
|
|
536
|
-
(base as OutputSymbol).instanceMemberScope,
|
|
537
|
-
name,
|
|
538
|
-
).value;
|
|
539
|
-
} else {
|
|
540
|
-
return undefined;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
return base;
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
650
|
}
|
|
549
651
|
|
|
550
652
|
/**
|
|
@@ -560,25 +662,44 @@ export function createOutputBinder(options: BinderOptions = {}): Binder {
|
|
|
560
662
|
export function resolve<
|
|
561
663
|
TScope extends OutputScope,
|
|
562
664
|
TSymbol extends OutputSymbol,
|
|
563
|
-
>(
|
|
665
|
+
>(
|
|
666
|
+
refkey: Refkey,
|
|
667
|
+
options: ResolveDeclarationByKeyOptions<TScope, TSymbol> = {},
|
|
668
|
+
): Ref<ResolutionResult<TScope, TSymbol>> {
|
|
564
669
|
const scope = useScope();
|
|
565
|
-
const memberScope =
|
|
566
|
-
const binder =
|
|
567
|
-
scope?.binder ??
|
|
568
|
-
memberScope?.instanceMembers?.binder ??
|
|
569
|
-
memberScope?.staticMembers?.binder;
|
|
670
|
+
const memberScope = useMemberContext();
|
|
671
|
+
const binder = scope?.binder ?? memberScope?.ownerSymbol.binder;
|
|
570
672
|
|
|
571
673
|
if (!binder) {
|
|
572
674
|
throw new Error("Can't resolve refkey without a binder");
|
|
573
675
|
}
|
|
574
676
|
|
|
575
677
|
return binder.resolveDeclarationByKey(
|
|
576
|
-
scope,
|
|
577
|
-
memberScope?.instanceMembers,
|
|
678
|
+
scope as TScope,
|
|
578
679
|
refkey,
|
|
680
|
+
options,
|
|
579
681
|
) as any;
|
|
580
682
|
}
|
|
581
683
|
|
|
684
|
+
/**
|
|
685
|
+
* Get a ref to the symbol for the given refkey using the current binder. The
|
|
686
|
+
* value of the ref will be undefined when no symbol with that refkey has been
|
|
687
|
+
* created.
|
|
688
|
+
*
|
|
689
|
+
* @remarks
|
|
690
|
+
*
|
|
691
|
+
* This API may return a ref for undefined, but that does not mean that the symbol is
|
|
692
|
+
* not found. The symbol you're looking for may not have been declared yet. When the symbol
|
|
693
|
+
* is declared, the ref will be updated with the symbol.
|
|
694
|
+
*/
|
|
695
|
+
export function symbolForRefkey(refkey: Refkey) {
|
|
696
|
+
const binder = useBinder();
|
|
697
|
+
if (!binder) {
|
|
698
|
+
throw new Error("Can't resolve refkey without a binder");
|
|
699
|
+
}
|
|
700
|
+
return binder.getSymbolForRefkey(refkey);
|
|
701
|
+
}
|
|
702
|
+
|
|
582
703
|
const createSymbolsSymbol: unique symbol = Symbol();
|
|
583
704
|
export function getSymbolCreator(
|
|
584
705
|
creator: SymbolCreator,
|
|
@@ -593,29 +714,3 @@ export function getSymbolCreatorSymbol(): typeof createSymbolsSymbol {
|
|
|
593
714
|
export interface SymbolCreator {
|
|
594
715
|
[createSymbolsSymbol](binder: Binder): void;
|
|
595
716
|
}
|
|
596
|
-
|
|
597
|
-
/**
|
|
598
|
-
* Use symbol flags to determine the scope in which a symbol with those flags
|
|
599
|
-
* should be declared given the current context.
|
|
600
|
-
*
|
|
601
|
-
* @param flags - The symbol flags to use to determine the default scope.
|
|
602
|
-
* @returns an {@link OutputScope} that is the default scope for the given
|
|
603
|
-
* flags.
|
|
604
|
-
*/
|
|
605
|
-
export function useDefaultScope(
|
|
606
|
-
flags: OutputSymbolFlags = OutputSymbolFlags.None,
|
|
607
|
-
) {
|
|
608
|
-
if ((flags & OutputSymbolFlags.Member) === 0) {
|
|
609
|
-
return useScope();
|
|
610
|
-
} else {
|
|
611
|
-
const memberScope = useMemberScope();
|
|
612
|
-
if (!memberScope) {
|
|
613
|
-
throw new Error("Cannot declare member symbols without a member scope");
|
|
614
|
-
}
|
|
615
|
-
if (flags & OutputSymbolFlags.InstanceMember) {
|
|
616
|
-
return memberScope.instanceMembers;
|
|
617
|
-
} else {
|
|
618
|
-
return memberScope.staticMembers;
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
}
|