@alloy-js/core 0.20.0-dev.3 → 0.20.0-dev.6
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 +62 -38
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +214 -173
- 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 +8 -2
- 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 +9 -5
- 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 +37 -15
- package/dist/src/components/Output.d.ts.map +1 -1
- package/dist/src/components/Output.js +2 -5
- package/dist/src/components/ReferenceOrContent.d.ts +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
- 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 +9 -5
- 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 +5 -5
- package/dist/src/context/name-policy.d.ts.map +1 -1
- package/dist/src/context/name-policy.js +3 -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 +7 -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 +5 -0
- package/dist/src/inspect.d.ts +2 -0
- package/dist/src/inspect.d.ts.map +1 -0
- package/dist/src/inspect.js +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 +3 -0
- package/dist/src/reactive-union-set.d.ts.map +1 -1
- package/dist/src/reactive-union-set.js +12 -8
- package/dist/src/refkey.d.ts +39 -3
- package/dist/src/refkey.d.ts.map +1 -1
- package/dist/src/refkey.js +52 -8
- 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 +20 -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 +28 -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 +3 -1
- 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 +98 -130
- 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 +35 -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 +323 -203
- 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 +22 -7
- 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 +20 -4
- 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 +65 -16
- package/dist/src/tracer.d.ts +15 -3
- package/dist/src/tracer.d.ts.map +1 -1
- package/dist/src/tracer.js +39 -63
- package/dist/src/utils.d.ts +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +4 -4
- package/dist/src/write-output.d.ts +1 -1
- package/dist/src/write-output.d.ts.map +1 -1
- package/dist/src/write-output.js +31 -37
- package/dist/test/components/declaration.test.js +9 -14
- package/dist/test/components/reference-or-content.test.js +2 -2
- package/dist/test/symbols/output-scope.test.js +33 -198
- package/dist/test/symbols/output-symbol.test.js +139 -385
- package/dist/test/symbols/resolution.test.js +431 -114
- 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 +14 -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 +23 -45
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
- package/src/binder.ts +348 -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 +88 -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/src/utils.tsx +4 -4
- package/src/write-output.ts +33 -45
- package/temp/api.json +5551 -3066
- 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
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
isRef,
|
|
2
3
|
reactive,
|
|
3
4
|
ReactiveFlags,
|
|
5
|
+
Ref,
|
|
4
6
|
shallowReactive,
|
|
5
7
|
track,
|
|
6
8
|
TrackOpTypes,
|
|
@@ -10,27 +12,88 @@ import {
|
|
|
10
12
|
} from "@vue/reactivity";
|
|
11
13
|
import type { Binder } from "../binder.js";
|
|
12
14
|
import { useBinder } from "../context/binder.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
15
|
+
import { inspect } from "../inspect.js";
|
|
16
|
+
import { NamePolicyGetter } from "../name-policy.js";
|
|
17
|
+
import { untrack } from "../reactivity.js";
|
|
18
|
+
import { Namekey, type Refkey } from "../refkey.js";
|
|
16
19
|
import {
|
|
17
|
-
formatScopeName,
|
|
18
20
|
formatSymbol,
|
|
19
21
|
formatSymbolName,
|
|
20
22
|
trace,
|
|
21
23
|
traceEffect,
|
|
22
24
|
TracePhase,
|
|
23
25
|
} from "../tracer.js";
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
+
import {
|
|
27
|
+
OutputDeclarationSpace,
|
|
28
|
+
OutputMemberSpace,
|
|
29
|
+
OutputSpace,
|
|
30
|
+
} from "./output-space.js";
|
|
31
|
+
import { SymbolTable } from "./symbol-table.js";
|
|
26
32
|
|
|
27
33
|
export interface OutputSymbolOptions {
|
|
34
|
+
/**
|
|
35
|
+
* The binder instance associated with this symbol. Symbol updates and changes
|
|
36
|
+
* will be reported to this binder. This binder will be able to find this
|
|
37
|
+
* symbol via its refkey and other means. Without a binder, this symbol will
|
|
38
|
+
* be unbound, which means it cannot be referenced by refkey.
|
|
39
|
+
*/
|
|
28
40
|
binder?: Binder;
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The refkey or refkeys associated with this symbol.
|
|
44
|
+
*/
|
|
31
45
|
refkeys?: Refkey | Refkey[];
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Arbitrary metadata about this symbol.
|
|
49
|
+
*/
|
|
32
50
|
metadata?: Record<string, unknown>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The symbol this symbol is an alias for.
|
|
54
|
+
*/
|
|
33
55
|
aliasTarget?: OutputSymbol;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Whether this symbol is transient.
|
|
59
|
+
*/
|
|
60
|
+
transient?: boolean;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The symbol that provides type information for this symbol. When present,
|
|
64
|
+
* this symbol will not contain its own members, and instead members will be
|
|
65
|
+
* provided by the type. This can be provided a Ref, in which case the type
|
|
66
|
+
* will be the value of that ref.
|
|
67
|
+
*/
|
|
68
|
+
type?: OutputSymbol | Ref<OutputSymbol | undefined>;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* When provided, this symbol will be named according to the provided name
|
|
72
|
+
* policy.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* const classNamer = useNamePolicy().for("class");
|
|
78
|
+
* const symbol = new BasicSymbol("my-class", { namePolicy: classNamer });
|
|
79
|
+
* console.log(symbol.name); // "MyClass" (assuming a PascalCase class naming policy)
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
namePolicy?: NamePolicyGetter;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Whether the name of this symbol should bypass the active name policy. When true,
|
|
86
|
+
* the name of this symbol will be fixed, though it may conflict with other symbols which are
|
|
87
|
+
* also ignoring the name policy.
|
|
88
|
+
*/
|
|
89
|
+
ignoreNamePolicy?: boolean;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Whether the name of this symbol should bypass the active name conflict resolution.
|
|
93
|
+
* When true, the name of this symbol will be fixed, though it may conflict with other symbols which are
|
|
94
|
+
* also ignoring name conflict resolution.
|
|
95
|
+
*/
|
|
96
|
+
ignoreNameConflict?: boolean;
|
|
34
97
|
}
|
|
35
98
|
|
|
36
99
|
let symbolCount = 0;
|
|
@@ -45,17 +108,32 @@ let symbolCount = 0;
|
|
|
45
108
|
* subtypes that provide additional metadata. Symbols are reactive values, so
|
|
46
109
|
* you can observe changes to their properties in a reactive context.
|
|
47
110
|
*/
|
|
48
|
-
export class OutputSymbol {
|
|
111
|
+
export abstract class OutputSymbol {
|
|
112
|
+
public static readonly memberSpaces: Readonly<string[]> = [];
|
|
113
|
+
|
|
49
114
|
#originalName: string;
|
|
115
|
+
/**
|
|
116
|
+
* Read only. The requested name of this symbol. The symbol's actual name may
|
|
117
|
+
* be different depending on naming policy or conflicts with other symbols.
|
|
118
|
+
*
|
|
119
|
+
* @readonly
|
|
120
|
+
*/
|
|
50
121
|
get originalName() {
|
|
51
122
|
return this.#originalName;
|
|
52
123
|
}
|
|
53
124
|
|
|
54
|
-
|
|
125
|
+
// this field is set by calling the name accessor.
|
|
126
|
+
#name!: string;
|
|
127
|
+
/**
|
|
128
|
+
* The name of this symbol.
|
|
129
|
+
*
|
|
130
|
+
* @reactive
|
|
131
|
+
*/
|
|
55
132
|
get name() {
|
|
56
133
|
track(this, TrackOpTypes.GET, "name");
|
|
57
134
|
return this.#name;
|
|
58
135
|
}
|
|
136
|
+
|
|
59
137
|
set name(name: string) {
|
|
60
138
|
const old = this.#name;
|
|
61
139
|
|
|
@@ -63,81 +141,139 @@ export class OutputSymbol {
|
|
|
63
141
|
return;
|
|
64
142
|
}
|
|
65
143
|
|
|
66
|
-
this.#name =
|
|
144
|
+
this.#name =
|
|
145
|
+
this.#namePolicy && !this.#ignoreNamePolicy ?
|
|
146
|
+
this.#namePolicy(name)
|
|
147
|
+
: name;
|
|
67
148
|
trigger(this, TriggerOpTypes.SET, "name", name, old);
|
|
68
149
|
}
|
|
69
150
|
|
|
70
151
|
#id: number;
|
|
152
|
+
/**
|
|
153
|
+
* The unique id of this symbol.
|
|
154
|
+
*
|
|
155
|
+
* @readonly
|
|
156
|
+
*/
|
|
71
157
|
get id() {
|
|
72
158
|
return this.#id;
|
|
73
159
|
}
|
|
74
160
|
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
161
|
+
#ignoreNamePolicy: boolean = false;
|
|
162
|
+
/**
|
|
163
|
+
* Whether the name of this symbol bypasses the active name policy. When true,
|
|
164
|
+
* the name of this symbol will be fixed, though it may conflict with other
|
|
165
|
+
* symbols which are also ignoring the name policy.
|
|
166
|
+
*
|
|
167
|
+
* @readonly
|
|
168
|
+
*/
|
|
169
|
+
get ignoreNamePolicy() {
|
|
170
|
+
return this.#ignoreNamePolicy;
|
|
79
171
|
}
|
|
80
|
-
set flags(flags: OutputSymbolFlags) {
|
|
81
|
-
const old = this.#flags;
|
|
82
|
-
|
|
83
|
-
if (old === flags) {
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
172
|
|
|
87
|
-
|
|
88
|
-
trigger(this, TriggerOpTypes.SET, "flags", flags, old);
|
|
173
|
+
#ignoreNameConflict: boolean = false;
|
|
89
174
|
|
|
90
|
-
|
|
91
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Whether the name of this symbol bypasses the active name conflict
|
|
177
|
+
* resolution. When true, the name of this symbol will be fixed, though it may
|
|
178
|
+
* conflict with other symbols which are also ignoring name conflict
|
|
179
|
+
* resolution.
|
|
180
|
+
*/
|
|
181
|
+
get ignoreNameConflict() {
|
|
182
|
+
return this.#ignoreNameConflict;
|
|
92
183
|
}
|
|
93
184
|
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
185
|
+
#memberSpaces: Record<string, OutputMemberSpace> = shallowReactive({});
|
|
186
|
+
/**
|
|
187
|
+
* The member spaces of this symbol.
|
|
188
|
+
*
|
|
189
|
+
* @readonly
|
|
190
|
+
*/
|
|
191
|
+
get memberSpaces() {
|
|
192
|
+
return Object.values(this.#memberSpaces);
|
|
98
193
|
}
|
|
99
194
|
|
|
100
|
-
|
|
101
|
-
|
|
195
|
+
/**
|
|
196
|
+
* Get the member space for the given key.
|
|
197
|
+
*/
|
|
198
|
+
memberSpaceFor(spaceKey: string): OutputMemberSpace | undefined {
|
|
199
|
+
return this.#memberSpaces[spaceKey];
|
|
200
|
+
}
|
|
102
201
|
|
|
103
|
-
|
|
104
|
-
|
|
202
|
+
/**
|
|
203
|
+
* The scope this symbol is in. When this symbol is a member symbol, this will
|
|
204
|
+
* return undefined.
|
|
205
|
+
*
|
|
206
|
+
* @readonly
|
|
207
|
+
*/
|
|
208
|
+
get scope() {
|
|
209
|
+
if (this.isMemberSymbol) {
|
|
210
|
+
return undefined;
|
|
105
211
|
}
|
|
106
212
|
|
|
107
|
-
this
|
|
213
|
+
if (this.spaces.length === 0) {
|
|
214
|
+
return undefined;
|
|
215
|
+
}
|
|
108
216
|
|
|
109
|
-
this
|
|
217
|
+
return (this.spaces[0] as OutputDeclarationSpace).scope;
|
|
218
|
+
}
|
|
110
219
|
|
|
111
|
-
|
|
220
|
+
#spaces: OutputSpace[];
|
|
221
|
+
/**
|
|
222
|
+
* The declaration or member spaces this symbol belongs to.
|
|
223
|
+
*
|
|
224
|
+
* @reactive
|
|
225
|
+
*/
|
|
226
|
+
get spaces(): OutputSpace[] {
|
|
227
|
+
track(this, TrackOpTypes.GET, "spaces");
|
|
228
|
+
return this.#spaces;
|
|
112
229
|
}
|
|
113
230
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// ensure when changing scope that this symbol only belongs to one of them
|
|
117
|
-
oldScope.symbols.delete(this);
|
|
118
|
-
}
|
|
231
|
+
set spaces(spaces: OutputSpace[] | OutputSpace | undefined) {
|
|
232
|
+
const old = this.#spaces;
|
|
119
233
|
|
|
120
|
-
if (
|
|
234
|
+
if (old === spaces) {
|
|
121
235
|
return;
|
|
122
236
|
}
|
|
123
237
|
|
|
124
|
-
|
|
238
|
+
const spacesArray =
|
|
239
|
+
spaces === undefined ? []
|
|
240
|
+
: Array.isArray(spaces) ? spaces
|
|
241
|
+
: [spaces];
|
|
242
|
+
this.#handleNewSpaces(spacesArray, old);
|
|
243
|
+
|
|
244
|
+
this.#spaces = spacesArray;
|
|
125
245
|
|
|
126
|
-
|
|
127
|
-
|
|
246
|
+
trigger(this, TriggerOpTypes.SET, "spaces", spaces, old);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
#handleNewSpaces(newSpaces: SymbolTable[], oldSpaces?: SymbolTable[]) {
|
|
250
|
+
if (oldSpaces) {
|
|
251
|
+
// ensure when changing scope that this symbol only belongs to one of them
|
|
252
|
+
oldSpaces.forEach((oldSpace) => oldSpace.delete(this));
|
|
128
253
|
}
|
|
129
254
|
|
|
130
|
-
if (
|
|
131
|
-
|
|
255
|
+
if (newSpaces) {
|
|
256
|
+
newSpaces.forEach((newSpace) => newSpace.add(this));
|
|
132
257
|
}
|
|
133
258
|
}
|
|
134
259
|
|
|
135
260
|
#binder: Binder | undefined;
|
|
261
|
+
/**
|
|
262
|
+
* The binder that is tracking this symbol.
|
|
263
|
+
*
|
|
264
|
+
* @readonly
|
|
265
|
+
*/
|
|
136
266
|
get binder() {
|
|
137
267
|
return this.#binder;
|
|
138
268
|
}
|
|
139
269
|
|
|
140
270
|
#refkeys: Refkey[];
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* The refkeys for this symbol.
|
|
274
|
+
*
|
|
275
|
+
* @reactive
|
|
276
|
+
*/
|
|
141
277
|
get refkeys() {
|
|
142
278
|
track(this, TrackOpTypes.GET, "refkeys");
|
|
143
279
|
return this.#refkeys;
|
|
@@ -156,122 +292,225 @@ export class OutputSymbol {
|
|
|
156
292
|
trigger(this, TriggerOpTypes.SET, "refkeys", this.#refkeys, old);
|
|
157
293
|
}
|
|
158
294
|
|
|
159
|
-
#instanceMemberScope?: OutputScope;
|
|
160
|
-
get instanceMemberScope() {
|
|
161
|
-
track(this, TrackOpTypes.GET, "instanceMemberScope");
|
|
162
|
-
return this.#instanceMemberScope;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
295
|
#aliasTarget?: OutputSymbol;
|
|
296
|
+
/**
|
|
297
|
+
* The symbol that this symbol is an alias for.
|
|
298
|
+
*
|
|
299
|
+
* @readonly
|
|
300
|
+
*/
|
|
166
301
|
get aliasTarget() {
|
|
167
302
|
return this.#aliasTarget;
|
|
168
303
|
}
|
|
169
304
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
) {
|
|
175
|
-
return;
|
|
305
|
+
/**
|
|
306
|
+
* If this symbol is an alias for another symbol, return the the aliased symbol. Otherwise, return this symbol.
|
|
307
|
+
*/
|
|
308
|
+
dealias(): OutputSymbol {
|
|
309
|
+
if (this.#aliasTarget) {
|
|
310
|
+
return this.#aliasTarget.dealias();
|
|
176
311
|
}
|
|
312
|
+
return this;
|
|
313
|
+
}
|
|
177
314
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
);
|
|
186
|
-
trigger(
|
|
187
|
-
this,
|
|
188
|
-
TriggerOpTypes.SET,
|
|
189
|
-
"instanceMemberScope",
|
|
190
|
-
this.#instanceMemberScope,
|
|
191
|
-
undefined,
|
|
192
|
-
);
|
|
315
|
+
/**
|
|
316
|
+
* Whether this symbol is an alias for another symbol.
|
|
317
|
+
*
|
|
318
|
+
* @readonly
|
|
319
|
+
*/
|
|
320
|
+
get isAlias() {
|
|
321
|
+
return !!this.#aliasTarget;
|
|
193
322
|
}
|
|
194
323
|
|
|
324
|
+
#metadata: Record<string, unknown>;
|
|
195
325
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
326
|
+
* An arbitrary bag of metadata for this symbol. This property is read only,
|
|
327
|
+
* but the metadata is a reactive object.
|
|
328
|
+
*
|
|
329
|
+
* @readonly
|
|
198
330
|
*/
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
options: {
|
|
202
|
-
owner?: OutputSymbol;
|
|
203
|
-
flags?: OutputScopeFlags;
|
|
204
|
-
},
|
|
205
|
-
) {
|
|
206
|
-
return new OutputScope(name, {
|
|
207
|
-
binder: this.#binder,
|
|
208
|
-
owner: options.owner,
|
|
209
|
-
flags: options.flags,
|
|
210
|
-
});
|
|
331
|
+
get metadata() {
|
|
332
|
+
return this.#metadata;
|
|
211
333
|
}
|
|
212
334
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return
|
|
335
|
+
copyToSpace(space: OutputSpace) {
|
|
336
|
+
const copy = this.copy();
|
|
337
|
+
copy.spaces = space;
|
|
338
|
+
return copy;
|
|
217
339
|
}
|
|
218
340
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
341
|
+
/**
|
|
342
|
+
* Whether this symbol is a member of another symbol.
|
|
343
|
+
*
|
|
344
|
+
* @readonly
|
|
345
|
+
*/
|
|
346
|
+
get isMemberSymbol() {
|
|
347
|
+
return this.spaces[0] instanceof OutputMemberSpace;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* When this is a member symbol, this returns the symbol that this is symbol
|
|
352
|
+
* is a member of.
|
|
353
|
+
*/
|
|
354
|
+
get ownerSymbol(): OutputSymbol | undefined {
|
|
355
|
+
if (!this.isMemberSymbol) {
|
|
356
|
+
return undefined;
|
|
225
357
|
}
|
|
226
358
|
|
|
227
|
-
|
|
228
|
-
binder: this.#binder,
|
|
229
|
-
owner: this,
|
|
230
|
-
flags: OutputScopeFlags.StaticMemberScope,
|
|
231
|
-
});
|
|
232
|
-
trigger(
|
|
233
|
-
this,
|
|
234
|
-
TriggerOpTypes.SET,
|
|
235
|
-
"staticMemberScope",
|
|
236
|
-
this.#staticMemberScope,
|
|
237
|
-
undefined,
|
|
238
|
-
);
|
|
359
|
+
return (this.spaces[0] as OutputMemberSpace).symbol;
|
|
239
360
|
}
|
|
240
361
|
|
|
241
|
-
#
|
|
242
|
-
|
|
243
|
-
|
|
362
|
+
#isTransient: boolean;
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Whether this symbol is a transient symbol. Transient symbols cannot be
|
|
366
|
+
* referenced and are meant to be combined with other symbols.
|
|
367
|
+
*
|
|
368
|
+
* @readonly
|
|
369
|
+
*/
|
|
370
|
+
get isTransient(): boolean {
|
|
371
|
+
if (this.#isTransient) {
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (this.ownerSymbol) {
|
|
376
|
+
return this.ownerSymbol.isTransient;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return false;
|
|
244
380
|
}
|
|
245
381
|
|
|
382
|
+
#movedTo: OutputSymbol | undefined;
|
|
246
383
|
/**
|
|
247
|
-
*
|
|
248
|
-
*
|
|
384
|
+
* The symbol that this symbol's members have been moved to.
|
|
385
|
+
*
|
|
386
|
+
* @readonly
|
|
387
|
+
* @reactive
|
|
388
|
+
*/
|
|
389
|
+
get movedTo() {
|
|
390
|
+
track(this, TrackOpTypes.GET, "movedTo");
|
|
391
|
+
return this.#movedTo;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
#setMovedTo(value: OutputSymbol | undefined) {
|
|
395
|
+
this.#movedTo = value;
|
|
396
|
+
trigger(this, TriggerOpTypes.SET, "movedTo");
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Whether this symbol's members have been moved to another symbol.
|
|
401
|
+
*
|
|
402
|
+
* @reactive
|
|
249
403
|
*/
|
|
404
|
+
get isMoved() {
|
|
405
|
+
return this.movedTo !== undefined;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
#type: OutputSymbol | undefined;
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* The symbol which defines the type of this symbol. The type symbol provides
|
|
412
|
+
* information about the value this symbol contains, such as what members it
|
|
413
|
+
* has.
|
|
414
|
+
*
|
|
415
|
+
* @reactive
|
|
416
|
+
*/
|
|
417
|
+
get type() {
|
|
418
|
+
track(this, TrackOpTypes.GET, "type");
|
|
419
|
+
return this.#type;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
set type(value: OutputSymbol | Ref<OutputSymbol | undefined> | undefined) {
|
|
423
|
+
if (isRef(value)) {
|
|
424
|
+
watch(value, (newValue) => {
|
|
425
|
+
const old = this.#type;
|
|
426
|
+
this.#type = newValue && newValue.dealias();
|
|
427
|
+
trigger(this, TriggerOpTypes.SET, "type", newValue, old);
|
|
428
|
+
});
|
|
429
|
+
} else {
|
|
430
|
+
const old = this.#type;
|
|
431
|
+
this.#type = value && value.dealias();
|
|
432
|
+
trigger(this, TriggerOpTypes.SET, "type", value, old);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Whether this symbol has its symbol representing its type available.
|
|
438
|
+
*
|
|
439
|
+
* @readonly
|
|
440
|
+
* @reactive
|
|
441
|
+
*/
|
|
442
|
+
get hasTypeSymbol() {
|
|
443
|
+
return this.type !== undefined;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
#isTyped: boolean = false;
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Whether this symbol's members are provided by a type symbol. The
|
|
450
|
+
* `typeSymbol` property is this symbol. It may not be available yet, so check
|
|
451
|
+
* `hasTypeSymbol`.
|
|
452
|
+
*/
|
|
453
|
+
get isTyped() {
|
|
454
|
+
return this.#isTyped;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
#namePolicy: NamePolicyGetter | undefined;
|
|
458
|
+
get namePolicy() {
|
|
459
|
+
return this.#namePolicy;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Tell \@vue/reactivity that this symbol should never be wrapped in a reactive
|
|
463
|
+
// proxy.
|
|
250
464
|
[ReactiveFlags.SKIP] = true;
|
|
251
465
|
|
|
252
|
-
constructor(
|
|
466
|
+
constructor(
|
|
467
|
+
name: string | Namekey,
|
|
468
|
+
spaces: OutputSpace[] | OutputSpace | undefined,
|
|
469
|
+
options: OutputSymbolOptions = {},
|
|
470
|
+
) {
|
|
253
471
|
this.#binder = options.binder ?? useBinder();
|
|
254
|
-
this.#
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
this.#
|
|
262
|
-
|
|
263
|
-
OutputSymbolFlags.MemberContainer | OutputSymbolFlags.Member
|
|
472
|
+
this.#namePolicy = options.namePolicy;
|
|
473
|
+
|
|
474
|
+
if (typeof name === "string") {
|
|
475
|
+
this.#ignoreNameConflict = !!options.ignoreNameConflict;
|
|
476
|
+
this.#ignoreNamePolicy = !!options.ignoreNamePolicy;
|
|
477
|
+
this.name = name;
|
|
478
|
+
this.#originalName = name;
|
|
479
|
+
this.#refkeys = shallowReactive(
|
|
480
|
+
this.#normalizeRefkeyOption(options.refkeys),
|
|
264
481
|
);
|
|
482
|
+
} else {
|
|
483
|
+
this.#ignoreNameConflict =
|
|
484
|
+
name.options.ignoreNameConflict ?? !!options.ignoreNameConflict;
|
|
485
|
+
this.#ignoreNamePolicy =
|
|
486
|
+
name.options.ignoreNamePolicy ?? !!options.ignoreNamePolicy;
|
|
487
|
+
this.name = name.name;
|
|
488
|
+
this.#originalName = name.name;
|
|
489
|
+
this.#refkeys = shallowReactive([
|
|
490
|
+
name,
|
|
491
|
+
...this.#normalizeRefkeyOption(options.refkeys),
|
|
492
|
+
]);
|
|
265
493
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
494
|
+
|
|
495
|
+
this.#id = symbolCount++;
|
|
496
|
+
this.#spaces =
|
|
497
|
+
Array.isArray(spaces) ? spaces
|
|
498
|
+
: spaces === undefined ? []
|
|
499
|
+
: [spaces];
|
|
500
|
+
this.#aliasTarget = options.aliasTarget;
|
|
271
501
|
this.#metadata = reactive(options.metadata ?? {});
|
|
272
|
-
this.#
|
|
273
|
-
this.#
|
|
274
|
-
this
|
|
502
|
+
this.#isTransient = !!options.transient;
|
|
503
|
+
this.#isTyped = !!options.type;
|
|
504
|
+
this.type = options.type;
|
|
505
|
+
|
|
506
|
+
this.#handleNewSpaces(this.#spaces);
|
|
507
|
+
const constructor = this.constructor as typeof OutputSymbol;
|
|
508
|
+
this.#memberSpaces = Object.fromEntries(
|
|
509
|
+
constructor.memberSpaces.map((spaceKey) => [
|
|
510
|
+
spaceKey,
|
|
511
|
+
new OutputMemberSpace(this, spaceKey, this.#binder),
|
|
512
|
+
]),
|
|
513
|
+
);
|
|
275
514
|
|
|
276
515
|
trace(TracePhase.symbol.create, () => `${formatSymbol(this)}`);
|
|
277
516
|
traceEffect(TracePhase.symbol.update, () => {
|
|
@@ -280,104 +519,72 @@ export class OutputSymbol {
|
|
|
280
519
|
this.#binder?.notifySymbolCreated(this);
|
|
281
520
|
}
|
|
282
521
|
|
|
522
|
+
#normalizeRefkeyOption(refkeys: Refkey | Refkey[] | undefined) {
|
|
523
|
+
if (refkeys === undefined) {
|
|
524
|
+
return [];
|
|
525
|
+
} else if (Array.isArray(refkeys)) {
|
|
526
|
+
return refkeys;
|
|
527
|
+
} else {
|
|
528
|
+
return [refkeys];
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
283
532
|
delete() {
|
|
284
533
|
trace(TracePhase.symbol.delete, () => `${formatSymbolName(this)}`);
|
|
285
|
-
if (this.#
|
|
286
|
-
this.#
|
|
534
|
+
if (this.#spaces) {
|
|
535
|
+
this.#spaces.forEach((space) => space.delete(this));
|
|
287
536
|
}
|
|
288
537
|
|
|
289
538
|
this.#binder?.notifySymbolDeleted(this);
|
|
290
539
|
}
|
|
291
540
|
|
|
292
541
|
/**
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
* symbols are set to a composite refkey of the target symbol's refkey and the
|
|
297
|
-
* instantiated symbol's refkey.
|
|
542
|
+
* Move member symbols from this transient symbol to the target symbol. This is reactive -
|
|
543
|
+
* whenever a member is added to this symbol, it will be moved to the target
|
|
544
|
+
* symbol.
|
|
298
545
|
*/
|
|
299
|
-
|
|
546
|
+
moveMembersTo(targetSymbol: OutputSymbol): void {
|
|
300
547
|
if (this.#aliasTarget) {
|
|
301
|
-
return this.#aliasTarget.
|
|
548
|
+
return this.#aliasTarget.moveMembersTo(targetSymbol);
|
|
302
549
|
}
|
|
303
550
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
const from = this.#instanceMemberScope ?? this.#staticMemberScope;
|
|
309
|
-
|
|
310
|
-
if (from) {
|
|
311
|
-
targetSymbol.flags |= OutputSymbolFlags.StaticMemberContainer;
|
|
312
|
-
targetSymbol.#createStaticMemberScope();
|
|
313
|
-
targetSymbol.#staticMemberScope!.copySymbolsFrom(from, {
|
|
314
|
-
onAdd: (symbol) => {
|
|
315
|
-
const clone = symbol.copyToScope(
|
|
316
|
-
targetSymbol.#staticMemberScope!,
|
|
317
|
-
targetSymbol,
|
|
318
|
-
);
|
|
319
|
-
clone.#flags &= ~OutputSymbolFlags.InstanceMember;
|
|
320
|
-
clone.#flags |= OutputSymbolFlags.StaticMember;
|
|
321
|
-
return clone;
|
|
322
|
-
},
|
|
323
|
-
});
|
|
551
|
+
if (!this.isTransient) {
|
|
552
|
+
throw new Error("Can only move members from transient symbols");
|
|
324
553
|
}
|
|
325
|
-
}
|
|
326
554
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
555
|
+
for (const sourceSpace of this.memberSpaces) {
|
|
556
|
+
const targetSpace = targetSymbol.memberSpaceFor(sourceSpace.key);
|
|
557
|
+
if (!targetSpace) {
|
|
558
|
+
throw new Error(
|
|
559
|
+
"Target symbol doesn't have member space " + sourceSpace.key,
|
|
560
|
+
);
|
|
332
561
|
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
return instantiationRks;
|
|
336
|
-
}
|
|
337
562
|
|
|
338
|
-
|
|
339
|
-
* Copy member symbols from the target symbol into the target symbol. The
|
|
340
|
-
* copied symbols have their refkey set to
|
|
341
|
-
* `refkey(targetSymbol.refkey, this.refkey)`.
|
|
342
|
-
*/
|
|
343
|
-
copyTo(targetSymbol: OutputSymbol): void {
|
|
344
|
-
if (this.#aliasTarget) {
|
|
345
|
-
return this.#aliasTarget.copyTo(targetSymbol);
|
|
346
|
-
}
|
|
347
|
-
if (this.staticMemberScope) {
|
|
348
|
-
targetSymbol.flags |= OutputSymbolFlags.StaticMemberContainer;
|
|
349
|
-
targetSymbol.staticMemberScope!.copySymbolsFrom(this.staticMemberScope);
|
|
563
|
+
sourceSpace.moveTo(targetSpace);
|
|
350
564
|
}
|
|
351
565
|
|
|
352
|
-
|
|
353
|
-
targetSymbol.flags |= OutputSymbolFlags.InstanceMemberContainer;
|
|
354
|
-
targetSymbol.instanceMemberScope!.copySymbolsFrom(
|
|
355
|
-
this.instanceMemberScope,
|
|
356
|
-
);
|
|
357
|
-
}
|
|
566
|
+
this.#setMovedTo(targetSymbol);
|
|
358
567
|
}
|
|
359
568
|
|
|
360
569
|
/**
|
|
361
|
-
*
|
|
570
|
+
* Copy the members of this symbol to the target symbol. This is reactive -
|
|
571
|
+
* whenever a member is added to this symbol, it will be copied to the target
|
|
572
|
+
* symbol.
|
|
362
573
|
*/
|
|
363
|
-
|
|
574
|
+
copyMembersTo(targetSymbol: OutputSymbol): void {
|
|
364
575
|
if (this.#aliasTarget) {
|
|
365
|
-
return this.#aliasTarget.
|
|
576
|
+
return this.#aliasTarget.copyMembersTo(targetSymbol);
|
|
366
577
|
}
|
|
367
578
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
579
|
+
for (const sourceSpace of this.memberSpaces) {
|
|
580
|
+
const targetSpace = targetSymbol.memberSpaceFor(sourceSpace.key);
|
|
581
|
+
if (!targetSpace) {
|
|
582
|
+
throw new Error(
|
|
583
|
+
"Target symbol doesn't have member space " + sourceSpace.key,
|
|
584
|
+
);
|
|
585
|
+
}
|
|
375
586
|
|
|
376
|
-
|
|
377
|
-
targetSymbol.flags |= OutputSymbolFlags.InstanceMemberContainer;
|
|
378
|
-
targetSymbol.instanceMemberScope!.moveSymbolsFrom(
|
|
379
|
-
this.instanceMemberScope,
|
|
380
|
-
);
|
|
587
|
+
sourceSpace.copyTo(targetSpace);
|
|
381
588
|
}
|
|
382
589
|
}
|
|
383
590
|
|
|
@@ -394,66 +601,35 @@ export class OutputSymbol {
|
|
|
394
601
|
*
|
|
395
602
|
* @param newScope - The scope to use for the copy.
|
|
396
603
|
*/
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
flags: this.#flags,
|
|
408
|
-
refkeys: baseSymbol ? this.#instantiationRk(baseSymbol, this) : [],
|
|
409
|
-
metadata: this.#metadata,
|
|
410
|
-
});
|
|
604
|
+
abstract copy(): OutputSymbol;
|
|
605
|
+
|
|
606
|
+
protected getCopyOptions() {
|
|
607
|
+
return {
|
|
608
|
+
binder: this.binder,
|
|
609
|
+
aliasTarget: this.aliasTarget,
|
|
610
|
+
metadata: this.metadata,
|
|
611
|
+
transient: this.isTransient,
|
|
612
|
+
};
|
|
613
|
+
}
|
|
411
614
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
});
|
|
416
|
-
}
|
|
615
|
+
protected initializeCopy(copy: OutputSymbol) {
|
|
616
|
+
for (const sourceSpace of this.memberSpaces) {
|
|
617
|
+
const targetSpace = copy.memberSpaceFor(sourceSpace.key);
|
|
417
618
|
|
|
418
|
-
|
|
419
|
-
|
|
619
|
+
if (!targetSpace) {
|
|
620
|
+
throw new Error("Target doesn't have space " + sourceSpace.key);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
sourceSpace.copyTo(targetSpace);
|
|
420
624
|
}
|
|
421
625
|
|
|
422
626
|
watch(
|
|
423
627
|
() => this.name,
|
|
424
|
-
(newName) => (
|
|
425
|
-
);
|
|
426
|
-
watch(
|
|
427
|
-
() => this.flags,
|
|
428
|
-
(newFlags) => (clone.flags = newFlags),
|
|
628
|
+
(newName) => (copy.name = newName),
|
|
429
629
|
);
|
|
430
|
-
|
|
431
|
-
return clone;
|
|
432
630
|
}
|
|
433
631
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
return useScope();
|
|
437
|
-
} else {
|
|
438
|
-
const memberScope = useMemberScope();
|
|
439
|
-
if (!memberScope) {
|
|
440
|
-
throw new Error("Cannot declare member symbols without a member scope");
|
|
441
|
-
}
|
|
442
|
-
if (this.#flags & OutputSymbolFlags.InstanceMember) {
|
|
443
|
-
if (!memberScope.instanceMembers) {
|
|
444
|
-
throw new Error(
|
|
445
|
-
"Cannot declare instance member symbols without an instance member scope",
|
|
446
|
-
);
|
|
447
|
-
}
|
|
448
|
-
return memberScope.instanceMembers;
|
|
449
|
-
} else {
|
|
450
|
-
if (!memberScope.staticMembers) {
|
|
451
|
-
throw new Error(
|
|
452
|
-
"Cannot declare static member symbols without a static member scope",
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
return memberScope.staticMembers;
|
|
456
|
-
}
|
|
457
|
-
}
|
|
632
|
+
[inspect.custom]() {
|
|
633
|
+
return untrack(() => `${this.constructor.name} "${this.name}"[${this.id}]`);
|
|
458
634
|
}
|
|
459
635
|
}
|