@alloy-js/core 0.15.0 → 0.17.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.
Files changed (175) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/src/binder.d.ts +18 -235
  3. package/dist/src/binder.d.ts.map +1 -1
  4. package/dist/src/binder.js +85 -386
  5. package/dist/src/components/Block.d.ts +1 -1
  6. package/dist/src/components/Block.d.ts.map +1 -1
  7. package/dist/src/components/Block.js +3 -1
  8. package/dist/src/components/Declaration.d.ts +1 -1
  9. package/dist/src/components/Declaration.d.ts.map +1 -1
  10. package/dist/src/components/Declaration.js +5 -4
  11. package/dist/src/components/For.d.ts +1 -1
  12. package/dist/src/components/For.d.ts.map +1 -1
  13. package/dist/src/components/For.js +1 -1
  14. package/dist/src/components/Indent.d.ts +1 -1
  15. package/dist/src/components/Indent.d.ts.map +1 -1
  16. package/dist/src/components/List.d.ts +1 -1
  17. package/dist/src/components/List.d.ts.map +1 -1
  18. package/dist/src/components/List.js +2 -1
  19. package/dist/src/components/MemberDeclaration.d.ts +1 -1
  20. package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
  21. package/dist/src/components/MemberDeclaration.js +3 -4
  22. package/dist/src/components/MemberScope.d.ts +1 -1
  23. package/dist/src/components/MemberScope.d.ts.map +1 -1
  24. package/dist/src/components/MemberScope.js +0 -2
  25. package/dist/src/components/Prose.d.ts +1 -1
  26. package/dist/src/components/Prose.d.ts.map +1 -1
  27. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  28. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  29. package/dist/src/components/Scope.d.ts +1 -1
  30. package/dist/src/components/Scope.d.ts.map +1 -1
  31. package/dist/src/components/Scope.js +3 -6
  32. package/dist/src/components/Show.d.ts +1 -1
  33. package/dist/src/components/Show.d.ts.map +1 -1
  34. package/dist/src/components/StatementList.d.ts +1 -1
  35. package/dist/src/components/StatementList.d.ts.map +1 -1
  36. package/dist/src/components/StatementList.js +1 -1
  37. package/dist/src/components/Switch.d.ts +1 -1
  38. package/dist/src/components/Switch.d.ts.map +1 -1
  39. package/dist/src/components/Switch.js +1 -1
  40. package/dist/src/components/Wrap.d.ts +1 -1
  41. package/dist/src/components/Wrap.d.ts.map +1 -1
  42. package/dist/src/context/assignment.d.ts +1 -1
  43. package/dist/src/context/assignment.d.ts.map +1 -1
  44. package/dist/src/context/binder.d.ts +2 -2
  45. package/dist/src/context/binder.d.ts.map +1 -1
  46. package/dist/src/context/declaration.d.ts +1 -1
  47. package/dist/src/context/declaration.d.ts.map +1 -1
  48. package/dist/src/context/member-declaration.d.ts +1 -1
  49. package/dist/src/context/member-declaration.d.ts.map +1 -1
  50. package/dist/src/context/member-declaration.js +0 -1
  51. package/dist/src/context/member-scope.d.ts +1 -1
  52. package/dist/src/context/member-scope.d.ts.map +1 -1
  53. package/dist/src/context/name-policy.d.ts +1 -1
  54. package/dist/src/context/name-policy.d.ts.map +1 -1
  55. package/dist/src/context/scope.d.ts +1 -1
  56. package/dist/src/context/scope.d.ts.map +1 -1
  57. package/dist/src/context/source-directory.d.ts +1 -1
  58. package/dist/src/context/source-directory.d.ts.map +1 -1
  59. package/dist/src/context/source-file.d.ts +2 -2
  60. package/dist/src/context/source-file.d.ts.map +1 -1
  61. package/dist/src/index.d.ts +4 -1
  62. package/dist/src/index.d.ts.map +1 -1
  63. package/dist/src/index.js +4 -1
  64. package/dist/src/jsx-runtime.d.ts +12 -3
  65. package/dist/src/jsx-runtime.d.ts.map +1 -1
  66. package/dist/src/jsx-runtime.js +6 -2
  67. package/dist/src/reactive-union-set.d.ts +29 -0
  68. package/dist/src/reactive-union-set.d.ts.map +1 -0
  69. package/dist/src/reactive-union-set.js +183 -0
  70. package/dist/src/refkey.d.ts +36 -0
  71. package/dist/src/refkey.d.ts.map +1 -1
  72. package/dist/src/refkey.js +40 -0
  73. package/dist/src/scheduler.d.ts +2 -2
  74. package/dist/src/scheduler.d.ts.map +1 -1
  75. package/dist/src/scheduler.js +27 -6
  76. package/dist/src/slot.d.ts +1 -1
  77. package/dist/src/slot.d.ts.map +1 -1
  78. package/dist/src/stc.d.ts +1 -1
  79. package/dist/src/stc.d.ts.map +1 -1
  80. package/dist/src/sti.d.ts +1 -1
  81. package/dist/src/sti.d.ts.map +1 -1
  82. package/dist/src/sti.js +1 -1
  83. package/dist/src/symbols/index.d.ts +6 -0
  84. package/dist/src/symbols/index.d.ts.map +1 -0
  85. package/dist/src/symbols/index.js +5 -0
  86. package/dist/src/symbols/output-scope.d.ts +116 -0
  87. package/dist/src/symbols/output-scope.d.ts.map +1 -0
  88. package/dist/src/symbols/output-scope.js +246 -0
  89. package/dist/src/symbols/output-symbol.d.ts +134 -0
  90. package/dist/src/symbols/output-symbol.d.ts.map +1 -0
  91. package/dist/src/symbols/output-symbol.js +379 -0
  92. package/dist/src/symbols/symbol-flow.d.ts +13 -0
  93. package/dist/src/symbols/symbol-flow.d.ts.map +1 -0
  94. package/dist/src/symbols/symbol-flow.js +74 -0
  95. package/dist/src/symbols/symbol-slot.d.ts +12 -0
  96. package/dist/src/symbols/symbol-slot.d.ts.map +1 -0
  97. package/dist/src/symbols/symbol-slot.js +36 -0
  98. package/dist/src/symbols/symbol-table.d.ts +14 -0
  99. package/dist/src/symbols/symbol-table.d.ts.map +1 -0
  100. package/dist/src/symbols/symbol-table.js +42 -0
  101. package/dist/src/tap.d.ts +2 -1
  102. package/dist/src/tap.d.ts.map +1 -1
  103. package/dist/src/tracer.d.ts +181 -0
  104. package/dist/src/tracer.d.ts.map +1 -0
  105. package/dist/src/tracer.js +441 -0
  106. package/dist/src/tsdoc-metadata.json +1 -1
  107. package/dist/test/components/slot.test.js +5 -7
  108. package/dist/test/reactive-union-set.test.d.ts +2 -0
  109. package/dist/test/reactive-union-set.test.d.ts.map +1 -0
  110. package/dist/test/reactive-union-set.test.js +170 -0
  111. package/dist/test/symbols/output-scope.test.d.ts +2 -0
  112. package/dist/test/symbols/output-scope.test.d.ts.map +1 -0
  113. package/dist/test/symbols/output-scope.test.js +342 -0
  114. package/dist/test/symbols/output-symbol.test.d.ts +2 -0
  115. package/dist/test/symbols/output-symbol.test.d.ts.map +1 -0
  116. package/dist/test/symbols/output-symbol.test.js +446 -0
  117. package/dist/test/symbols/resolution.test.d.ts +2 -0
  118. package/dist/test/symbols/resolution.test.d.ts.map +1 -0
  119. package/dist/test/symbols/resolution.test.js +140 -0
  120. package/dist/test/symbols/utils.d.ts +24 -0
  121. package/dist/test/symbols/utils.d.ts.map +1 -0
  122. package/dist/test/symbols/utils.js +46 -0
  123. package/dist/tsconfig.tsbuildinfo +1 -1
  124. package/package.json +3 -3
  125. package/src/binder.ts +148 -672
  126. package/src/components/Block.tsx +4 -1
  127. package/src/components/Declaration.tsx +6 -6
  128. package/src/components/For.tsx +1 -1
  129. package/src/components/Indent.tsx +1 -1
  130. package/src/components/List.tsx +1 -1
  131. package/src/components/MemberDeclaration.tsx +4 -4
  132. package/src/components/MemberScope.tsx +2 -5
  133. package/src/components/Prose.tsx +1 -1
  134. package/src/components/ReferenceOrContent.tsx +1 -1
  135. package/src/components/Scope.tsx +2 -6
  136. package/src/components/Show.tsx +1 -1
  137. package/src/components/StatementList.tsx +2 -1
  138. package/src/components/Switch.tsx +1 -1
  139. package/src/components/Wrap.tsx +1 -1
  140. package/src/context/assignment.ts +1 -1
  141. package/src/context/binder.ts +2 -2
  142. package/src/context/declaration.ts +1 -1
  143. package/src/context/member-declaration.ts +1 -1
  144. package/src/context/member-scope.ts +1 -1
  145. package/src/context/name-policy.ts +1 -1
  146. package/src/context/scope.ts +1 -1
  147. package/src/context/source-directory.ts +1 -1
  148. package/src/context/source-file.ts +2 -2
  149. package/src/index.ts +15 -0
  150. package/src/jsx-runtime.ts +18 -2
  151. package/src/reactive-union-set.ts +238 -0
  152. package/src/refkey.ts +40 -0
  153. package/src/scheduler.ts +31 -6
  154. package/src/slot.ts +1 -1
  155. package/src/stc.ts +3 -3
  156. package/src/sti.ts +5 -5
  157. package/src/symbols/index.ts +5 -0
  158. package/src/symbols/output-scope.ts +323 -0
  159. package/src/symbols/output-symbol.ts +512 -0
  160. package/src/symbols/symbol-flow.ts +104 -0
  161. package/src/symbols/symbol-slot.tsx +47 -0
  162. package/src/symbols/symbol-table.ts +72 -0
  163. package/src/tap.ts +2 -1
  164. package/src/tracer.ts +440 -0
  165. package/temp/api.json +4172 -1582
  166. package/test/components/slot.test.tsx +8 -11
  167. package/test/reactive-union-set.test.tsx +191 -0
  168. package/test/symbols/output-scope.test.ts +302 -0
  169. package/test/symbols/output-symbol.test.ts +459 -0
  170. package/test/symbols/resolution.test.ts +172 -0
  171. package/test/symbols/utils.ts +95 -0
  172. package/dist/test/symbols.test.d.ts +0 -2
  173. package/dist/test/symbols.test.d.ts.map +0 -1
  174. package/dist/test/symbols.test.js +0 -884
  175. package/test/symbols.test.ts +0 -1006
@@ -0,0 +1,379 @@
1
+ import { reactive, ReactiveFlags, shallowReactive, track, TrackOpTypes, trigger, TriggerOpTypes, watch } from "@vue/reactivity";
2
+ import { useBinder } from "../context/binder.js";
3
+ import { useMemberScope } from "../context/member-scope.js";
4
+ import { useScope } from "../context/scope.js";
5
+ import { isRefkey, refkey } from "../refkey.js";
6
+ import { formatScopeName, formatSymbol, formatSymbolName, trace, traceEffect, TracePhase } from "../tracer.js";
7
+ import { OutputScope, OutputScopeFlags } from "./output-scope.js";
8
+ /**
9
+ * Flags that describe an output symbol.
10
+ */
11
+ export let OutputSymbolFlags = /*#__PURE__*/function (OutputSymbolFlags) {
12
+ OutputSymbolFlags[OutputSymbolFlags["None"] = 0] = "None";
13
+ /**
14
+ * The symbol is an instance member container. Symbols with this flag will have a
15
+ * instanceMemberScope property that contains symbols for instance members.
16
+ */
17
+ OutputSymbolFlags[OutputSymbolFlags["InstanceMemberContainer"] = 1] = "InstanceMemberContainer";
18
+ /**
19
+ * The symbol is a static member container. Symbols with this flag will have a
20
+ * staticMemberScope property that contains symbols for static members.
21
+ */
22
+ OutputSymbolFlags[OutputSymbolFlags["StaticMemberContainer"] = 2] = "StaticMemberContainer";
23
+ /**
24
+ * Whether this symbol contains members of any kind.
25
+ */
26
+ OutputSymbolFlags[OutputSymbolFlags["MemberContainer"] = 3] = "MemberContainer";
27
+ /**
28
+ * Whether this symbol is an instance member of another symbol (i.e that it is
29
+ * stored in an instance member scope).
30
+ */
31
+ OutputSymbolFlags[OutputSymbolFlags["InstanceMember"] = 4] = "InstanceMember";
32
+ /**
33
+ * Whether this symbol is a static member of another symbol (i.e that it is
34
+ * stored in a static member scope).
35
+ */
36
+ OutputSymbolFlags[OutputSymbolFlags["StaticMember"] = 8] = "StaticMember";
37
+ /**
38
+ * Transient symbols are not added to symbol tables and do not create
39
+ * referencable refkeys. They are used for temporary symbols that are intended
40
+ * to be used to calculate other symbols.
41
+ */
42
+ OutputSymbolFlags[OutputSymbolFlags["Transient"] = 16] = "Transient";
43
+ /**
44
+ * This symbol aliases another symbol. Only its name, flags, and scope are
45
+ * stored in this symbol. Otherwise, everything else is located on the alias
46
+ * target.
47
+ */
48
+ OutputSymbolFlags[OutputSymbolFlags["Alias"] = 32] = "Alias";
49
+ /**
50
+ * Whether this is an instance member or static member of another symbol.
51
+ */
52
+ OutputSymbolFlags[OutputSymbolFlags["Member"] = 12] = "Member";
53
+ return OutputSymbolFlags;
54
+ }({});
55
+ let symbolCount = 0;
56
+
57
+ /**
58
+ * An output symbol is a named entity that can be referenced in your output
59
+ * code.
60
+ *
61
+ * @remarks
62
+ *
63
+ * This class is the base implementation of symbol. Most languages will have
64
+ * subtypes that provide additional metadata. Symbols are reactive values, so
65
+ * you can observe changes to their properties in a reactive context.
66
+ */
67
+ export class OutputSymbol {
68
+ #originalName;
69
+ get originalName() {
70
+ return this.#originalName;
71
+ }
72
+ #name;
73
+ get name() {
74
+ track(this, TrackOpTypes.GET, "name");
75
+ return this.#name;
76
+ }
77
+ set name(name) {
78
+ const old = this.#name;
79
+ if (old === name) {
80
+ return;
81
+ }
82
+ this.#name = name;
83
+ trigger(this, TriggerOpTypes.SET, "name", name, old);
84
+ }
85
+ #id;
86
+ get id() {
87
+ return this.#id;
88
+ }
89
+ #flags;
90
+ get flags() {
91
+ track(this, TrackOpTypes.GET, "flags");
92
+ return this.#flags;
93
+ }
94
+ set flags(flags) {
95
+ const old = this.#flags;
96
+ if (old === flags) {
97
+ return;
98
+ }
99
+ this.#flags = flags;
100
+ trigger(this, TriggerOpTypes.SET, "flags", flags, old);
101
+ this.#createInstanceMemberScope();
102
+ this.#createStaticMemberScope();
103
+ }
104
+ #scope;
105
+ get scope() {
106
+ track(this, TrackOpTypes.GET, "scope");
107
+ return this.#scope;
108
+ }
109
+ set scope(scope) {
110
+ const old = this.#scope;
111
+ if (old === scope) {
112
+ return;
113
+ }
114
+ this.#handleNewScope(scope, old);
115
+ this.#scope = scope;
116
+ trigger(this, TriggerOpTypes.SET, "scope", scope, old);
117
+ }
118
+ #handleNewScope(newScope, oldScope) {
119
+ if (oldScope) {
120
+ // ensure when changing scope that this symbol only belongs to one of them
121
+ oldScope.symbols.delete(this);
122
+ }
123
+ if (!newScope) {
124
+ return;
125
+ }
126
+ newScope.symbols.add(this);
127
+ if (newScope.flags & OutputScopeFlags.InstanceMemberScope) {
128
+ this.flags |= OutputSymbolFlags.InstanceMember;
129
+ }
130
+ if (newScope.flags & OutputScopeFlags.StaticMemberScope) {
131
+ this.flags |= OutputSymbolFlags.StaticMember;
132
+ }
133
+ }
134
+ #binder;
135
+ get binder() {
136
+ return this.#binder;
137
+ }
138
+ #refkeys;
139
+ get refkeys() {
140
+ track(this, TrackOpTypes.GET, "refkeys");
141
+ return this.#refkeys;
142
+ }
143
+ set refkeys(refkeys) {
144
+ const old = this.#refkeys;
145
+ if (old === refkeys) {
146
+ return;
147
+ }
148
+ this.#refkeys = shallowReactive(Array.isArray(refkeys) ? refkeys : [refkeys]);
149
+ trigger(this, TriggerOpTypes.SET, "refkeys", this.#refkeys, old);
150
+ }
151
+ #instanceMemberScope;
152
+ get instanceMemberScope() {
153
+ track(this, TrackOpTypes.GET, "instanceMemberScope");
154
+ return this.#instanceMemberScope;
155
+ }
156
+ #aliasTarget;
157
+ get aliasTarget() {
158
+ return this.#aliasTarget;
159
+ }
160
+ #createInstanceMemberScope() {
161
+ if (this.#instanceMemberScope || !(this.#flags & OutputSymbolFlags.InstanceMemberContainer)) {
162
+ return;
163
+ }
164
+ this.#instanceMemberScope = new OutputScope(`${this.name} instance members`, {
165
+ binder: this.#binder,
166
+ owner: this,
167
+ flags: OutputScopeFlags.InstanceMemberScope
168
+ });
169
+ trigger(this, TriggerOpTypes.SET, "instanceMemberScope", this.#instanceMemberScope, undefined);
170
+ }
171
+
172
+ /**
173
+ * Create an output scope to hold member symbols. By default this just creates
174
+ * an OutputScope, but can be subclassed to build scope subtypes when needed.
175
+ */
176
+ createMemberScope(name, options) {
177
+ return new OutputScope(name, {
178
+ binder: this.#binder,
179
+ owner: options.owner,
180
+ flags: options.flags
181
+ });
182
+ }
183
+ #staticMemberScope;
184
+ get staticMemberScope() {
185
+ track(this, TrackOpTypes.GET, "staticMemberScope");
186
+ return this.#staticMemberScope;
187
+ }
188
+ #createStaticMemberScope() {
189
+ if (this.#staticMemberScope || !(this.#flags & OutputSymbolFlags.StaticMemberContainer)) {
190
+ return;
191
+ }
192
+ this.#staticMemberScope = new OutputScope(`${this.name} static members`, {
193
+ binder: this.#binder,
194
+ owner: this,
195
+ flags: OutputScopeFlags.StaticMemberScope
196
+ });
197
+ trigger(this, TriggerOpTypes.SET, "staticMemberScope", this.#staticMemberScope, undefined);
198
+ }
199
+ #metadata;
200
+ get metadata() {
201
+ return this.#metadata;
202
+ }
203
+
204
+ /**
205
+ * Tell \@vue/reactivity that this symbol should never be wrapped in a reactive
206
+ * proxy.
207
+ */
208
+ [ReactiveFlags.SKIP] = true;
209
+ constructor(name, options = {}) {
210
+ this.#binder = options.binder ?? useBinder();
211
+ this.#name = name;
212
+ this.#originalName = name;
213
+ this.#id = symbolCount++;
214
+ this.#flags = options.flags ?? OutputSymbolFlags.None;
215
+ this.#scope = options.scope ?? this.#defaultScope();
216
+ this.#aliasTarget = options.aliasTarget;
217
+ if (this.#aliasTarget) {
218
+ this.#flags |= OutputSymbolFlags.Alias;
219
+ this.#flags &= ~(OutputSymbolFlags.MemberContainer | OutputSymbolFlags.Member);
220
+ }
221
+ this.#refkeys = shallowReactive(Array.isArray(options.refkeys) ? options.refkeys : isRefkey(options.refkeys) ? [options.refkeys] : []);
222
+ this.#metadata = reactive(options.metadata ?? {});
223
+ this.#createInstanceMemberScope();
224
+ this.#createStaticMemberScope();
225
+ this.#handleNewScope(this.#scope);
226
+ trace(TracePhase.symbol.create, () => `${formatSymbol(this)}`);
227
+ traceEffect(TracePhase.symbol.update, () => {
228
+ return `${formatSymbol(this)}`;
229
+ });
230
+ this.#binder?.notifySymbolCreated(this);
231
+ }
232
+ delete() {
233
+ trace(TracePhase.symbol.delete, () => `${formatSymbolName(this)}`);
234
+ if (this.#scope) {
235
+ this.#scope.symbols.delete(this);
236
+ }
237
+ this.#binder?.notifySymbolDeleted(this);
238
+ }
239
+
240
+ /**
241
+ * Takes the instance members or static members on this symbol and creates
242
+ * corresponding static members on the target symbol. Instance or static
243
+ * members of instantiated symbols are copied. The refkey of any instantiated
244
+ * symbols are set to a composite refkey of the target symbol's refkey and the
245
+ * instantiated symbol's refkey.
246
+ */
247
+ instantiateTo(targetSymbol) {
248
+ if (this.#aliasTarget) {
249
+ return this.#aliasTarget.instantiateTo(targetSymbol);
250
+ }
251
+ trace(TracePhase.symbol.instantiate, () => {
252
+ return `${formatSymbolName(this)} -> ${formatSymbolName(targetSymbol)}`;
253
+ });
254
+ const from = this.#instanceMemberScope ?? this.#staticMemberScope;
255
+ if (from) {
256
+ targetSymbol.flags |= OutputSymbolFlags.StaticMemberContainer;
257
+ targetSymbol.#createStaticMemberScope();
258
+ targetSymbol.#staticMemberScope.copySymbolsFrom(from, {
259
+ onAdd: symbol => {
260
+ const clone = symbol.copyToScope(targetSymbol.#staticMemberScope, targetSymbol);
261
+ clone.#flags &= ~OutputSymbolFlags.InstanceMember;
262
+ clone.#flags |= OutputSymbolFlags.StaticMember;
263
+ return clone;
264
+ }
265
+ });
266
+ }
267
+ }
268
+ #instantiationRk(base, member) {
269
+ const instantiationRks = [];
270
+ for (const baseRk of base.refkeys) {
271
+ for (const targetRk of member.refkeys) {
272
+ instantiationRks.push(refkey(baseRk, targetRk));
273
+ }
274
+ }
275
+ return instantiationRks;
276
+ }
277
+
278
+ /**
279
+ * Copy member symbols from the target symbol into the target symbol. The
280
+ * copied symbols have their refkey set to
281
+ * `refkey(targetSymbol.refkey, this.refkey)`.
282
+ */
283
+ copyTo(targetSymbol) {
284
+ if (this.#aliasTarget) {
285
+ return this.#aliasTarget.copyTo(targetSymbol);
286
+ }
287
+ if (this.staticMemberScope) {
288
+ targetSymbol.flags |= OutputSymbolFlags.StaticMemberContainer;
289
+ targetSymbol.staticMemberScope.copySymbolsFrom(this.staticMemberScope);
290
+ }
291
+ if (this.instanceMemberScope) {
292
+ targetSymbol.flags |= OutputSymbolFlags.InstanceMemberContainer;
293
+ targetSymbol.instanceMemberScope.copySymbolsFrom(this.instanceMemberScope);
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Move member symbols from this transient symbol to the target symbol.
299
+ */
300
+ moveTo(targetSymbol) {
301
+ if (this.#aliasTarget) {
302
+ return this.#aliasTarget.moveTo(targetSymbol);
303
+ }
304
+ if (!(this.flags & OutputSymbolFlags.Transient)) {
305
+ throw new Error("Can only move members from transient symbols");
306
+ }
307
+ if (this.staticMemberScope) {
308
+ targetSymbol.flags |= OutputSymbolFlags.StaticMemberContainer;
309
+ targetSymbol.staticMemberScope.moveSymbolsFrom(this.staticMemberScope);
310
+ }
311
+ if (this.instanceMemberScope) {
312
+ targetSymbol.flags |= OutputSymbolFlags.InstanceMemberContainer;
313
+ targetSymbol.instanceMemberScope.moveSymbolsFrom(this.instanceMemberScope);
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Makes a copy of this symbol which will update the name and flags
319
+ * of the clone when the original symbol is updated.
320
+ *
321
+ * @remarks
322
+ *
323
+ * This is used to create a symbol that is a copy of this symbol, but
324
+ * with a different scope. Changes to the copy will not affect the
325
+ * original symbol, and changes to the original symbol's name and flags
326
+ * will overwrite the copy's name and flags.
327
+ *
328
+ * @param newScope - The scope to use for the copy.
329
+ */
330
+ copyToScope(newScope, baseSymbol) {
331
+ if (this.#aliasTarget) {
332
+ return this.#aliasTarget.copyToScope(newScope, baseSymbol);
333
+ }
334
+ trace(TracePhase.symbol.clone, () => {
335
+ return `${formatSymbolName(this)} -> ${formatScopeName(newScope)}`;
336
+ });
337
+ const clone = new OutputSymbol(this.#name, {
338
+ binder: this.#binder,
339
+ scope: newScope,
340
+ flags: this.#flags,
341
+ refkeys: baseSymbol ? this.#instantiationRk(baseSymbol, this) : [],
342
+ metadata: this.#metadata
343
+ });
344
+ if (this.instanceMemberScope) {
345
+ clone.#instanceMemberScope = this.instanceMemberScope.clone({
346
+ owner: clone
347
+ });
348
+ }
349
+ if (this.staticMemberScope) {
350
+ clone.#staticMemberScope = this.staticMemberScope.clone({
351
+ owner: clone
352
+ });
353
+ }
354
+ watch(() => this.name, newName => clone.name = newName);
355
+ watch(() => this.flags, newFlags => clone.flags = newFlags);
356
+ return clone;
357
+ }
358
+ #defaultScope() {
359
+ if ((this.#flags & OutputSymbolFlags.Member) === 0) {
360
+ return useScope();
361
+ } else {
362
+ const memberScope = useMemberScope();
363
+ if (!memberScope) {
364
+ throw new Error("Cannot declare member symbols without a member scope");
365
+ }
366
+ if (this.#flags & OutputSymbolFlags.InstanceMember) {
367
+ if (!memberScope.instanceMembers) {
368
+ throw new Error("Cannot declare instance member symbols without an instance member scope");
369
+ }
370
+ return memberScope.instanceMembers;
371
+ } else {
372
+ if (!memberScope.staticMembers) {
373
+ throw new Error("Cannot declare static member symbols without a static member scope");
374
+ }
375
+ return memberScope.staticMembers;
376
+ }
377
+ }
378
+ }
379
+ }
@@ -0,0 +1,13 @@
1
+ import { Ref } from "@vue/reactivity";
2
+ import { OutputSymbol } from "./output-symbol.js";
3
+ export interface TakeSymbolCallback {
4
+ (symbol: OutputSymbol): void;
5
+ }
6
+ export interface TakeSymbolsCallback {
7
+ (symbols: Set<OutputSymbol>): void;
8
+ }
9
+ export declare function takeSymbols(cb?: (symbol: OutputSymbol) => void): import("@vue/reactivity").ShallowReactive<Set<OutputSymbol>>;
10
+ export declare function emitSymbol(symbol: OutputSymbol | Ref<OutputSymbol | undefined>): void;
11
+ export declare function moveTakenMembersTo(baseSymbol: OutputSymbol): void;
12
+ export declare function instantiateTakenMembersTo(baseSymbol: OutputSymbol): void;
13
+ //# sourceMappingURL=symbol-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbol-flow.d.ts","sourceRoot":"","sources":["../../../src/symbols/symbol-flow.ts"],"names":[],"mappings":"AAMA,OAAO,EAAS,GAAG,EAAmB,MAAM,iBAAiB,CAAC;AAI9D,OAAO,EAAE,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,CAAC,OAAO,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;CACpC;AAED,wBAAgB,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,gEAiB9D;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,YAAY,GAAG,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC,QA+CrD;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,YAAY,QAU1D;AAED,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,YAAY,QAEjE"}
@@ -0,0 +1,74 @@
1
+ import { effect, getContext, onCleanup } from "@alloy-js/core/jsx-runtime";
2
+ import { isRef, shallowReactive } from "@vue/reactivity";
3
+ import { MemberScopeContext } from "../context/member-scope.js";
4
+ import { ScopeContext } from "../context/scope.js";
5
+ import { OutputSymbolFlags } from "./output-symbol.js";
6
+ export function takeSymbols(cb) {
7
+ const context = getContext();
8
+ context.takesSymbols = true;
9
+ context.takenSymbols = shallowReactive(new Set());
10
+ if (cb) {
11
+ effect(oldSymbols => {
12
+ for (const symbol of context.takenSymbols) {
13
+ if (oldSymbols && oldSymbols.has(symbol)) {
14
+ continue;
15
+ }
16
+ cb(symbol);
17
+ }
18
+ return new Set(context.takenSymbols);
19
+ });
20
+ }
21
+ return context.takenSymbols;
22
+ }
23
+ export function emitSymbol(symbol) {
24
+ let symbolTaker;
25
+ let context = getContext().owner;
26
+ while (context) {
27
+ if (context.takesSymbols) {
28
+ symbolTaker = context;
29
+ break;
30
+ }
31
+ if (context.context && (context.context[ScopeContext.id] || context.context[MemberScopeContext.id])) {
32
+ // don't cross scope boundaries.
33
+ break;
34
+ }
35
+ context = context.owner;
36
+ }
37
+ if (!symbolTaker) {
38
+ return;
39
+ }
40
+ if (isRef(symbol)) {
41
+ effect(prevSymbol => {
42
+ onCleanup(() => {
43
+ if (symbol.value) {
44
+ symbolTaker.takenSymbols.delete(symbol.value);
45
+ }
46
+ });
47
+ if (symbol.value === undefined) {
48
+ symbolTaker.takenSymbols.delete(prevSymbol);
49
+ return undefined;
50
+ } else {
51
+ symbolTaker.takenSymbols.add(symbol.value);
52
+ return symbol.value;
53
+ }
54
+ });
55
+ } else {
56
+ symbolTaker.takenSymbols.add(symbol);
57
+ onCleanup(() => {
58
+ context.takenSymbols.delete(symbol);
59
+ });
60
+ }
61
+ }
62
+ export function moveTakenMembersTo(baseSymbol) {
63
+ const taken = takeSymbols();
64
+ effect(() => {
65
+ for (const symbol of taken) {
66
+ if (symbol.flags & OutputSymbolFlags.Transient) {
67
+ symbol.moveTo(baseSymbol);
68
+ }
69
+ }
70
+ });
71
+ }
72
+ export function instantiateTakenMembersTo(baseSymbol) {
73
+ takeSymbols(symbol => symbol.instantiateTo(baseSymbol));
74
+ }
@@ -0,0 +1,12 @@
1
+ import { Ref, ShallowReactive } from "@vue/reactivity";
2
+ import { Children } from "../jsx-runtime.js";
3
+ import { OutputSymbol } from "./output-symbol.js";
4
+ export declare function createSymbolSlot(): {
5
+ (props: {
6
+ children: Children;
7
+ }): Children;
8
+ ref: Ref<ShallowReactive<Set<OutputSymbol>> | undefined, ShallowReactive<Set<OutputSymbol>> | undefined>;
9
+ instantiateInto(baseSymbol: OutputSymbol): void;
10
+ copyInto(baseSymbol: OutputSymbol): void;
11
+ };
12
+ //# sourceMappingURL=symbol-slot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbol-slot.d.ts","sourceRoot":"","sources":["../../../src/symbols/symbol-slot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,eAAe,EAAc,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAqB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,wBAAgB,gBAAgB;YAGH;QAAE,QAAQ,EAAE,QAAQ,CAAA;KAAE;;gCAaP,YAAY;yBAYnB,YAAY;EAahD"}
@@ -0,0 +1,36 @@
1
+ import { shallowRef } from "@vue/reactivity";
2
+ import { effect, onCleanup } from "../jsx-runtime.js";
3
+ import { takeSymbols } from "./symbol-flow.js";
4
+ export function createSymbolSlot() {
5
+ const symbolSlotRef = shallowRef();
6
+ function SymbolSlot(props) {
7
+ const set = takeSymbols();
8
+ symbolSlotRef.value = set;
9
+ onCleanup(() => {
10
+ symbolSlotRef.value = undefined;
11
+ });
12
+ return props.children;
13
+ }
14
+ SymbolSlot.ref = symbolSlotRef;
15
+ SymbolSlot.instantiateInto = baseSymbol => {
16
+ effect(() => {
17
+ if (!symbolSlotRef.value) {
18
+ return;
19
+ }
20
+ for (const symbol of symbolSlotRef.value) {
21
+ symbol.instantiateTo(baseSymbol);
22
+ }
23
+ });
24
+ };
25
+ SymbolSlot.copyInto = baseSymbol => {
26
+ effect(() => {
27
+ if (!symbolSlotRef.value) {
28
+ return;
29
+ }
30
+ for (const symbol of symbolSlotRef.value) {
31
+ symbol.copyTo(baseSymbol);
32
+ }
33
+ });
34
+ };
35
+ return SymbolSlot;
36
+ }
@@ -0,0 +1,14 @@
1
+ import { NameConflictResolver } from "../binder.js";
2
+ import { ReactiveUnionSet } from "../reactive-union-set.js";
3
+ import { OutputScope } from "./output-scope.js";
4
+ import { OutputSymbol } from "./output-symbol.js";
5
+ export declare class SymbolTable extends ReactiveUnionSet<OutputSymbol> {
6
+ private _namesToDeconflict;
7
+ private _nameConflictResolver?;
8
+ private _deconflictNames;
9
+ scope: OutputScope;
10
+ constructor(scope: OutputScope, options?: {
11
+ nameConflictResolver?: NameConflictResolver;
12
+ });
13
+ }
14
+ //# sourceMappingURL=symbol-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbol-table.d.ts","sourceRoot":"","sources":["../../../src/symbols/symbol-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAQ5D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,qBAAa,WAAY,SAAQ,gBAAgB,CAAC,YAAY,CAAC;IAC7D,OAAO,CAAC,kBAAkB,CAA0B;IACpD,OAAO,CAAC,qBAAqB,CAAC,CAAuB;IACrD,OAAO,CAAC,gBAAgB,CAYtB;IACK,KAAK,cAAC;gBAEX,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE;QACP,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;KACxC;CA2BT"}
@@ -0,0 +1,42 @@
1
+ import { ReactiveUnionSet } from "../reactive-union-set.js";
2
+ import { queueJob } from "../scheduler.js";
3
+ import { formatScopeName, formatSymbolName, trace, TracePhase } from "../tracer.js";
4
+ export class SymbolTable extends ReactiveUnionSet {
5
+ _namesToDeconflict = new Set();
6
+ _deconflictNames = () => {
7
+ for (const name of this._namesToDeconflict) {
8
+ const conflictedSymbols = [...this].filter(sym => sym.originalName === name);
9
+ if (this._nameConflictResolver) {
10
+ this._nameConflictResolver(name, conflictedSymbols);
11
+ } else {
12
+ defaultConflictHandler(name, conflictedSymbols);
13
+ }
14
+ this._namesToDeconflict.delete(name);
15
+ }
16
+ };
17
+ constructor(scope, options = {}) {
18
+ super({
19
+ onAdd: symbol => {
20
+ trace(TracePhase.symbol.addToScope, () => `${formatSymbolName(symbol)} -> ${formatScopeName(scope)}`);
21
+ this._namesToDeconflict.add(symbol.name);
22
+ queueJob(this._deconflictNames);
23
+ return symbol;
24
+ },
25
+ onDelete(symbol) {
26
+ trace(TracePhase.symbol.removeFromScope, () => `${formatSymbolName(symbol)} -> ${formatScopeName(scope)}`);
27
+ }
28
+ });
29
+ this.scope = scope;
30
+ this._nameConflictResolver = options.nameConflictResolver;
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Default conflict handler. This will rename all but the first symbol
36
+ * to have a suffix of _2, _3, etc.
37
+ */
38
+ function defaultConflictHandler(_, conflictedSymbols) {
39
+ for (let i = 1; i < conflictedSymbols.length; i++) {
40
+ conflictedSymbols[i].name = conflictedSymbols[i].originalName + "_" + (i + 1);
41
+ }
42
+ }
package/dist/src/tap.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { ShallowRef } from "@vue/reactivity";
2
- import { OutputScope, OutputSymbol } from "./binder.js";
3
2
  import { SourceFileContext } from "./context/source-file.js";
4
3
  import { ComponentDefinition } from "./jsx-runtime.js";
4
+ import { OutputScope } from "./symbols/output-scope.js";
5
+ import { OutputSymbol } from "./symbols/output-symbol.js";
5
6
  /**
6
7
  * The return value of {@link createTap}, this holds a reference to the tapped
7
8
  * value. It will be undefined until the tapped value is initialized.
@@ -1 +1 @@
1
- {"version":3,"file":"tap.d.ts","sourceRoot":"","sources":["../../src/tap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAc,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,GAAG,CAAC,CAAC,CAAE,SAAQ,mBAAmB;IACjD,+BAA+B;IAC/B,GAAG,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG,SAAS,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,OAAO,EACnC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GACtB,GAAG,CAAC,CAAC,CAAC,CAcR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,SAAS,YAAY,GAAG,YAAY,EAC3C,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,gBAI9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,SAAS,YAAY,GAAG,YAAY,EACzE,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,gBAK9B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,SAAS,WAAW,GAAG,WAAW,EACrE,OAAO,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,eAK7B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,0BAI1E"}
1
+ {"version":3,"file":"tap.d.ts","sourceRoot":"","sources":["../../src/tap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAc,MAAM,iBAAiB,CAAC;AAKzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,GAAG,CAAC,CAAC,CAAE,SAAQ,mBAAmB;IACjD,+BAA+B;IAC/B,GAAG,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG,SAAS,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,OAAO,EACnC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,OAAO,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,GACtB,GAAG,CAAC,CAAC,CAAC,CAcR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,SAAS,YAAY,GAAG,YAAY,EAC3C,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,gBAI9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,SAAS,YAAY,GAAG,YAAY,EACzE,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,gBAK9B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,SAAS,WAAW,GAAG,WAAW,EACrE,OAAO,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,eAK7B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,0BAI1E"}