@alloy-js/core 0.16.0 → 0.18.0-dev.2

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 (249) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/src/binder.d.ts +19 -235
  3. package/dist/src/binder.d.ts.map +1 -1
  4. package/dist/src/binder.js +85 -386
  5. package/dist/src/code.d.ts +1 -1
  6. package/dist/src/code.d.ts.map +1 -1
  7. package/dist/src/components/Block.d.ts +1 -1
  8. package/dist/src/components/Block.d.ts.map +1 -1
  9. package/dist/src/components/Block.js +3 -1
  10. package/dist/src/components/Declaration.d.ts +2 -2
  11. package/dist/src/components/Declaration.d.ts.map +1 -1
  12. package/dist/src/components/Declaration.js +6 -5
  13. package/dist/src/components/For.d.ts +1 -1
  14. package/dist/src/components/For.d.ts.map +1 -1
  15. package/dist/src/components/For.js +1 -1
  16. package/dist/src/components/Indent.d.ts +1 -1
  17. package/dist/src/components/Indent.d.ts.map +1 -1
  18. package/dist/src/components/List.d.ts +1 -1
  19. package/dist/src/components/List.d.ts.map +1 -1
  20. package/dist/src/components/List.js +3 -1
  21. package/dist/src/components/MemberDeclaration.d.ts +3 -3
  22. package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
  23. package/dist/src/components/MemberDeclaration.js +4 -4
  24. package/dist/src/components/MemberScope.d.ts +2 -2
  25. package/dist/src/components/MemberScope.d.ts.map +1 -1
  26. package/dist/src/components/MemberScope.js +0 -2
  27. package/dist/src/components/Output.d.ts +1 -1
  28. package/dist/src/components/Output.d.ts.map +1 -1
  29. package/dist/src/components/Output.js +1 -1
  30. package/dist/src/components/Prose.d.ts +1 -1
  31. package/dist/src/components/Prose.d.ts.map +1 -1
  32. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  33. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  34. package/dist/src/components/Scope.d.ts +2 -2
  35. package/dist/src/components/Scope.d.ts.map +1 -1
  36. package/dist/src/components/Scope.js +3 -6
  37. package/dist/src/components/Show.d.ts +1 -1
  38. package/dist/src/components/Show.d.ts.map +1 -1
  39. package/dist/src/components/SourceDirectory.d.ts +1 -1
  40. package/dist/src/components/SourceDirectory.d.ts.map +1 -1
  41. package/dist/src/components/SourceDirectory.js +1 -1
  42. package/dist/src/components/SourceFile.d.ts +1 -1
  43. package/dist/src/components/SourceFile.d.ts.map +1 -1
  44. package/dist/src/components/SourceFile.js +1 -1
  45. package/dist/src/components/StatementList.d.ts +1 -1
  46. package/dist/src/components/StatementList.d.ts.map +1 -1
  47. package/dist/src/components/StatementList.js +1 -1
  48. package/dist/src/components/Switch.d.ts +2 -2
  49. package/dist/src/components/Switch.d.ts.map +1 -1
  50. package/dist/src/components/Switch.js +2 -1
  51. package/dist/src/components/Wrap.d.ts +1 -1
  52. package/dist/src/components/Wrap.d.ts.map +1 -1
  53. package/dist/src/context/assignment.d.ts +1 -1
  54. package/dist/src/context/assignment.d.ts.map +1 -1
  55. package/dist/src/context/binder.d.ts +3 -3
  56. package/dist/src/context/binder.d.ts.map +1 -1
  57. package/dist/src/context/declaration.d.ts +1 -1
  58. package/dist/src/context/declaration.d.ts.map +1 -1
  59. package/dist/src/context/member-declaration.d.ts +1 -1
  60. package/dist/src/context/member-declaration.d.ts.map +1 -1
  61. package/dist/src/context/member-declaration.js +0 -1
  62. package/dist/src/context/member-scope.d.ts +1 -1
  63. package/dist/src/context/member-scope.d.ts.map +1 -1
  64. package/dist/src/context/name-policy.d.ts +1 -1
  65. package/dist/src/context/name-policy.d.ts.map +1 -1
  66. package/dist/src/context/scope.d.ts +1 -1
  67. package/dist/src/context/scope.d.ts.map +1 -1
  68. package/dist/src/context/source-directory.d.ts +1 -1
  69. package/dist/src/context/source-directory.d.ts.map +1 -1
  70. package/dist/src/context/source-file.d.ts +2 -2
  71. package/dist/src/context/source-file.d.ts.map +1 -1
  72. package/dist/src/context.d.ts +2 -2
  73. package/dist/src/context.d.ts.map +1 -1
  74. package/dist/src/context.js +1 -1
  75. package/dist/src/debug.d.ts +1 -0
  76. package/dist/src/debug.d.ts.map +1 -1
  77. package/dist/src/debug.js +4 -1
  78. package/dist/src/index.d.ts +8 -2
  79. package/dist/src/index.d.ts.map +1 -1
  80. package/dist/src/index.js +8 -2
  81. package/dist/src/jsx-runtime.d.ts +4 -272
  82. package/dist/src/jsx-runtime.d.ts.map +1 -1
  83. package/dist/src/jsx-runtime.js +3 -315
  84. package/dist/src/props-combinators.d.ts +19 -0
  85. package/dist/src/props-combinators.d.ts.map +1 -0
  86. package/dist/src/props-combinators.js +108 -0
  87. package/dist/src/reactive-union-set.d.ts +29 -0
  88. package/dist/src/reactive-union-set.d.ts.map +1 -0
  89. package/dist/src/reactive-union-set.js +183 -0
  90. package/dist/src/reactivity.d.ts +75 -0
  91. package/dist/src/reactivity.d.ts.map +1 -0
  92. package/dist/src/reactivity.js +141 -0
  93. package/dist/src/refkey.d.ts +36 -0
  94. package/dist/src/refkey.d.ts.map +1 -1
  95. package/dist/src/refkey.js +40 -0
  96. package/dist/src/render.d.ts +5 -1
  97. package/dist/src/render.d.ts.map +1 -1
  98. package/dist/src/render.js +68 -15
  99. package/dist/src/runtime/component.d.ts +24 -0
  100. package/dist/src/runtime/component.d.ts.map +1 -0
  101. package/dist/src/runtime/component.js +19 -0
  102. package/dist/src/runtime/intrinsic.d.ts +168 -0
  103. package/dist/src/runtime/intrinsic.d.ts.map +1 -0
  104. package/dist/src/runtime/intrinsic.js +11 -0
  105. package/dist/src/scheduler.d.ts +2 -2
  106. package/dist/src/scheduler.d.ts.map +1 -1
  107. package/dist/src/scheduler.js +27 -6
  108. package/dist/src/slot.d.ts +2 -2
  109. package/dist/src/slot.d.ts.map +1 -1
  110. package/dist/src/slot.js +1 -1
  111. package/dist/src/stc.d.ts +1 -1
  112. package/dist/src/stc.d.ts.map +1 -1
  113. package/dist/src/sti.d.ts +7 -6
  114. package/dist/src/sti.d.ts.map +1 -1
  115. package/dist/src/sti.js +1 -1
  116. package/dist/src/symbols/flags.d.ts +70 -0
  117. package/dist/src/symbols/flags.d.ts.map +1 -0
  118. package/dist/src/symbols/flags.js +72 -0
  119. package/dist/src/symbols/index.d.ts +7 -0
  120. package/dist/src/symbols/index.d.ts.map +1 -0
  121. package/dist/src/symbols/index.js +6 -0
  122. package/dist/src/symbols/output-scope.d.ts +94 -0
  123. package/dist/src/symbols/output-scope.d.ts.map +1 -0
  124. package/dist/src/symbols/output-scope.js +222 -0
  125. package/dist/src/symbols/output-symbol.d.ts +89 -0
  126. package/dist/src/symbols/output-symbol.d.ts.map +1 -0
  127. package/dist/src/symbols/output-symbol.js +333 -0
  128. package/dist/src/symbols/symbol-flow.d.ts +13 -0
  129. package/dist/src/symbols/symbol-flow.d.ts.map +1 -0
  130. package/dist/src/symbols/symbol-flow.js +74 -0
  131. package/dist/src/symbols/symbol-slot.d.ts +12 -0
  132. package/dist/src/symbols/symbol-slot.d.ts.map +1 -0
  133. package/dist/src/symbols/symbol-slot.js +36 -0
  134. package/dist/src/symbols/symbol-table.d.ts +14 -0
  135. package/dist/src/symbols/symbol-table.d.ts.map +1 -0
  136. package/dist/src/symbols/symbol-table.js +42 -0
  137. package/dist/src/tap.d.ts +3 -2
  138. package/dist/src/tap.d.ts.map +1 -1
  139. package/dist/src/tracer.d.ts +238 -0
  140. package/dist/src/tracer.d.ts.map +1 -0
  141. package/dist/src/tracer.js +496 -0
  142. package/dist/src/tsdoc-metadata.json +1 -1
  143. package/dist/src/utils.d.ts +4 -3
  144. package/dist/src/utils.d.ts.map +1 -1
  145. package/dist/src/utils.js +2 -1
  146. package/dist/test/components/slot.test.js +5 -7
  147. package/dist/test/props-with-defaults.test.js +1 -1
  148. package/dist/test/reactive-union-set.test.d.ts +2 -0
  149. package/dist/test/reactive-union-set.test.d.ts.map +1 -0
  150. package/dist/test/reactive-union-set.test.js +170 -0
  151. package/dist/test/reactivity/cleanup.test.js +2 -1
  152. package/dist/test/reactivity/memo.test.js +1 -1
  153. package/dist/test/reactivity/untrack.test.js +1 -1
  154. package/dist/test/rendering/memoization.test.js +2 -1
  155. package/dist/test/split-props.test.js +1 -1
  156. package/dist/test/symbols/output-scope.test.d.ts +2 -0
  157. package/dist/test/symbols/output-scope.test.d.ts.map +1 -0
  158. package/dist/test/symbols/output-scope.test.js +343 -0
  159. package/dist/test/symbols/output-symbol.test.d.ts +2 -0
  160. package/dist/test/symbols/output-symbol.test.d.ts.map +1 -0
  161. package/dist/test/symbols/output-symbol.test.js +447 -0
  162. package/dist/test/symbols/resolution.test.d.ts +2 -0
  163. package/dist/test/symbols/resolution.test.d.ts.map +1 -0
  164. package/dist/test/symbols/resolution.test.js +141 -0
  165. package/dist/test/symbols/utils.d.ts +25 -0
  166. package/dist/test/symbols/utils.d.ts.map +1 -0
  167. package/dist/test/symbols/utils.js +47 -0
  168. package/dist/testing/extend-expect.d.ts +15 -0
  169. package/dist/testing/extend-expect.d.ts.map +1 -1
  170. package/dist/testing/extend-expect.js +2 -1
  171. package/dist/testing/render.d.ts +1 -1
  172. package/dist/testing/render.d.ts.map +1 -1
  173. package/dist/tsconfig.tsbuildinfo +1 -1
  174. package/package.json +28 -24
  175. package/src/binder.ts +146 -672
  176. package/src/code.ts +1 -1
  177. package/src/components/Block.tsx +4 -1
  178. package/src/components/Declaration.tsx +8 -7
  179. package/src/components/For.tsx +2 -1
  180. package/src/components/Indent.tsx +1 -1
  181. package/src/components/List.tsx +3 -1
  182. package/src/components/MemberDeclaration.tsx +7 -6
  183. package/src/components/MemberScope.tsx +2 -5
  184. package/src/components/Output.tsx +2 -1
  185. package/src/components/Prose.tsx +1 -1
  186. package/src/components/ReferenceOrContent.tsx +1 -1
  187. package/src/components/Scope.tsx +3 -7
  188. package/src/components/Show.tsx +1 -1
  189. package/src/components/SourceDirectory.tsx +2 -1
  190. package/src/components/SourceFile.tsx +2 -1
  191. package/src/components/StatementList.tsx +2 -1
  192. package/src/components/Switch.tsx +2 -1
  193. package/src/components/Wrap.tsx +1 -1
  194. package/src/context/assignment.ts +1 -1
  195. package/src/context/binder.ts +3 -3
  196. package/src/context/declaration.ts +1 -1
  197. package/src/context/member-declaration.ts +1 -1
  198. package/src/context/member-scope.ts +1 -1
  199. package/src/context/name-policy.ts +1 -1
  200. package/src/context/scope.ts +1 -1
  201. package/src/context/source-directory.ts +1 -1
  202. package/src/context/source-file.ts +2 -2
  203. package/src/context.ts +3 -7
  204. package/src/debug.ts +5 -1
  205. package/src/index.ts +15 -1
  206. package/src/jsx-runtime.ts +15 -674
  207. package/src/props-combinators.ts +148 -0
  208. package/src/reactive-union-set.ts +238 -0
  209. package/src/reactivity.ts +230 -0
  210. package/src/refkey.ts +40 -0
  211. package/src/render.ts +97 -26
  212. package/src/runtime/component.ts +67 -0
  213. package/src/runtime/intrinsic.ts +199 -0
  214. package/src/scheduler.ts +31 -6
  215. package/src/slot.ts +3 -4
  216. package/src/stc.ts +2 -2
  217. package/src/sti.ts +11 -11
  218. package/src/symbols/flags.ts +82 -0
  219. package/src/symbols/index.ts +6 -0
  220. package/src/symbols/output-scope.ts +296 -0
  221. package/src/symbols/output-symbol.ts +459 -0
  222. package/src/symbols/symbol-flow.ts +100 -0
  223. package/src/symbols/symbol-slot.tsx +48 -0
  224. package/src/symbols/symbol-table.ts +72 -0
  225. package/src/tap.ts +3 -2
  226. package/src/tracer.ts +474 -0
  227. package/src/utils.tsx +7 -5
  228. package/temp/api.json +7446 -5133
  229. package/test/components/slot.test.tsx +8 -11
  230. package/test/props-with-defaults.test.ts +1 -1
  231. package/test/reactive-union-set.test.tsx +191 -0
  232. package/test/reactivity/cleanup.test.tsx +2 -1
  233. package/test/reactivity/memo.test.tsx +1 -1
  234. package/test/reactivity/untrack.test.ts +1 -1
  235. package/test/rendering/basic.test.tsx +1 -1
  236. package/test/rendering/memoization.test.tsx +1 -1
  237. package/test/split-props.test.ts +1 -1
  238. package/test/symbols/output-scope.test.ts +300 -0
  239. package/test/symbols/output-symbol.test.ts +456 -0
  240. package/test/symbols/resolution.test.ts +170 -0
  241. package/test/symbols/utils.ts +93 -0
  242. package/test/utils.test.tsx +1 -1
  243. package/testing/extend-expect.ts +16 -0
  244. package/testing/render.ts +1 -2
  245. package/LICENSE +0 -7
  246. package/dist/test/symbols.test.d.ts +0 -2
  247. package/dist/test/symbols.test.d.ts.map +0 -1
  248. package/dist/test/symbols.test.js +0 -884
  249. package/test/symbols.test.ts +0 -1006
@@ -0,0 +1,447 @@
1
+ import { reactive, watch } from "@vue/reactivity";
2
+ import { beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { createOutputBinder } from "../../src/binder.js";
4
+ import { MemberScopeContext } from "../../src/context/member-scope.js";
5
+ import { ScopeContext } from "../../src/index.browser.js";
6
+ import { renderTree } from "../../src/render.js";
7
+ import { flushJobs } from "../../src/scheduler.js";
8
+ import { OutputScopeFlags, OutputSymbolFlags } from "../../src/symbols/flags.js";
9
+ import { OutputScope } from "../../src/symbols/output-scope.js";
10
+ import { OutputSymbol } from "../../src/symbols/output-symbol.js";
11
+ let binder;
12
+ beforeEach(() => {
13
+ binder = createOutputBinder();
14
+ });
15
+ describe("OutputSymbol reactivity", () => {
16
+ it("keeps symbol names up-to-date", () => {
17
+ const scope = new OutputScope("scope", {
18
+ binder
19
+ });
20
+ const symbol = new OutputSymbol("sym", {
21
+ binder,
22
+ scope
23
+ });
24
+ flushJobs();
25
+ expect(scope.symbolNames.has("sym")).toBe(true);
26
+ symbol.name = "bar";
27
+ flushJobs();
28
+ expect(scope.symbolNames.has("bar")).toBe(true);
29
+ });
30
+ it("resolves symbol conflicts", () => {
31
+ const scope = new OutputScope("scope", {
32
+ binder
33
+ });
34
+ const s1 = new OutputSymbol("sym", {
35
+ binder,
36
+ scope
37
+ });
38
+ const s2 = new OutputSymbol("sym", {
39
+ binder,
40
+ scope
41
+ });
42
+ const s3 = new OutputSymbol("sym", {
43
+ binder,
44
+ scope
45
+ });
46
+ flushJobs();
47
+ expect(s1.name).toEqual("sym");
48
+ expect(s2.name).toEqual("sym_2");
49
+ expect(s3.name).toEqual("sym_3");
50
+ });
51
+ it("is reactive on name, flags, scope, instanceMemberScope, and staticMemberScope", () => {
52
+ const scope = new OutputScope("scope", {
53
+ binder
54
+ });
55
+ const symbol = new OutputSymbol("sym", {
56
+ binder,
57
+ scope
58
+ });
59
+ const nameSpy = vi.fn();
60
+ watch(() => symbol.name, nameSpy);
61
+ const flagsSpy = vi.fn();
62
+ watch(() => symbol.flags, flagsSpy);
63
+ const scopeSpy = vi.fn();
64
+ watch(() => symbol.scope, scopeSpy);
65
+ const instanceMemberScopeSpy = vi.fn();
66
+ watch(() => symbol.instanceMemberScope, instanceMemberScopeSpy);
67
+ const staticMemberScopeSpy = vi.fn();
68
+ watch(() => symbol.staticMemberScope, staticMemberScopeSpy);
69
+ symbol.name = "foo";
70
+ symbol.flags = 0;
71
+ symbol.scope = new OutputScope("new-scope", {
72
+ binder
73
+ });
74
+ symbol.flags |= OutputSymbolFlags.InstanceMemberContainer | OutputSymbolFlags.StaticMemberContainer;
75
+ expect(nameSpy).toHaveBeenCalled();
76
+ expect(flagsSpy).toHaveBeenCalled();
77
+ expect(scopeSpy).toHaveBeenCalled();
78
+ expect(instanceMemberScopeSpy).toHaveBeenCalled();
79
+ expect(staticMemberScopeSpy).toHaveBeenCalled();
80
+ });
81
+ it("doesn't get wrapped in a reactive proxy", () => {
82
+ const scope = new OutputScope("scope", {
83
+ binder
84
+ });
85
+ const symbol = new OutputSymbol("sym", {
86
+ binder,
87
+ scope
88
+ });
89
+ const rSymbol = reactive(symbol);
90
+ expect(rSymbol).toBe(symbol);
91
+ });
92
+ });
93
+ describe("OutputSymbol#flags", () => {
94
+ it("sets member flags based on parent scope", () => {
95
+ const scope = new OutputScope("scope", {
96
+ binder
97
+ });
98
+ const symbol = new OutputSymbol("sym", {
99
+ binder,
100
+ scope
101
+ });
102
+ expect(symbol.flags & OutputSymbolFlags.Member).toBeFalsy();
103
+ const memberScope = new OutputScope("member-scope", {
104
+ binder,
105
+ owner: symbol,
106
+ flags: OutputScopeFlags.InstanceMemberScope
107
+ });
108
+ const memberSymbol = new OutputSymbol("member-sym", {
109
+ binder,
110
+ scope: memberScope
111
+ });
112
+ expect(memberSymbol.flags & OutputSymbolFlags.InstanceMember).toBeTruthy();
113
+ });
114
+ });
115
+ describe("OutputSymbol#staticMemberScope", () => {
116
+ it("is created when needed", () => {
117
+ const scope = new OutputScope("scope", {
118
+ binder
119
+ });
120
+ const symbol = new OutputSymbol("sym", {
121
+ binder,
122
+ scope,
123
+ flags: OutputSymbolFlags.StaticMemberContainer
124
+ });
125
+ expect(symbol.staticMemberScope).toBeDefined();
126
+ expect(symbol.staticMemberScope.symbols.size).toEqual(0);
127
+ });
128
+ });
129
+ describe("OutputSymbol#instanceMemberScope", () => {
130
+ it("is created when needed", () => {
131
+ const scope = new OutputScope("scope", {
132
+ binder
133
+ });
134
+ const symbol = new OutputSymbol("sym", {
135
+ binder,
136
+ scope,
137
+ flags: OutputSymbolFlags.InstanceMemberContainer
138
+ });
139
+ expect(symbol.instanceMemberScope).toBeDefined();
140
+ expect(symbol.instanceMemberScope.symbols.size).toEqual(0);
141
+ });
142
+ });
143
+ describe("OutputSymbol#metadata", () => {
144
+ it("is reactive", () => {
145
+ const scope = new OutputScope("scope", {
146
+ binder
147
+ });
148
+ const symbol = new OutputSymbol("sym", {
149
+ binder,
150
+ scope,
151
+ metadata: {
152
+ foo: "bar"
153
+ }
154
+ });
155
+ const metadataSpy = vi.fn();
156
+ watch(() => symbol.metadata.foo, metadataSpy);
157
+ symbol.metadata.foo = "baz";
158
+ expect(metadataSpy).toHaveBeenCalled();
159
+ expect(symbol.metadata.foo).toEqual("baz");
160
+ });
161
+ });
162
+ describe("OutputSymbol#scope", () => {
163
+ it("adds to parent scope", () => {
164
+ const scope = new OutputScope("parent", {
165
+ binder
166
+ });
167
+ const symbol = new OutputSymbol("sym", {
168
+ binder,
169
+ scope
170
+ });
171
+ expect(scope.symbols.has(symbol)).toBe(true);
172
+ });
173
+ it("defaults to the current lexical scope when not a member", () => {
174
+ const scope = new OutputScope("parent", {
175
+ binder
176
+ });
177
+ withContext([[ScopeContext, scope]], () => {
178
+ const symbol = new OutputSymbol("sym", {
179
+ binder
180
+ });
181
+ expect(scope.symbols.has(symbol)).toBe(true);
182
+ });
183
+ });
184
+ it("defaults to the current member scope when a member", () => {
185
+ const symbol = new OutputSymbol("Class", {
186
+ binder,
187
+ scope: binder.globalScope,
188
+ flags: OutputSymbolFlags.MemberContainer
189
+ });
190
+ withContext([[MemberScopeContext, {
191
+ instanceMembers: symbol.instanceMemberScope,
192
+ staticMembers: symbol.staticMemberScope
193
+ }]], () => {
194
+ const ms = new OutputSymbol("ms", {
195
+ binder,
196
+ flags: OutputSymbolFlags.InstanceMember
197
+ });
198
+ const ss = new OutputSymbol("ss", {
199
+ binder,
200
+ flags: OutputSymbolFlags.StaticMember
201
+ });
202
+ expect(symbol.instanceMemberScope.symbols.has(ms)).toBe(true);
203
+ expect(symbol.staticMemberScope.symbols.has(ss)).toBe(true);
204
+ });
205
+ });
206
+ });
207
+ function withContext(contexts, fn) {
208
+ let children = fn;
209
+ for (let i = 0; i < contexts.length; i++) {
210
+ const [context, value] = contexts[i];
211
+ children = context.ProviderStc({
212
+ value
213
+ }).children(children);
214
+ }
215
+ renderTree(children);
216
+ }
217
+ describe("Symbol#delete", () => {
218
+ it("deletes from parent scope", () => {
219
+ const scope = new OutputScope("parent", {
220
+ binder
221
+ });
222
+ const symbol = new OutputSymbol("sym", {
223
+ binder,
224
+ scope
225
+ });
226
+ expect(scope.symbols.has(symbol)).toBe(true);
227
+ symbol.delete();
228
+ expect(scope.symbols.has(symbol)).toBe(false);
229
+ });
230
+ it("updates resolution");
231
+ });
232
+ describe("OutputSymbol#cloneInto", () => {
233
+ it("copies values and propagates updates", () => {
234
+ const scope = new OutputScope("scope", {
235
+ binder
236
+ });
237
+ const scope2 = new OutputScope("scope2", {
238
+ binder
239
+ });
240
+ const symbol = new OutputSymbol("sym", {
241
+ binder,
242
+ scope
243
+ });
244
+ const clone = symbol.copyToScope(scope2);
245
+ expect(clone.name).toEqual("sym");
246
+ expect(clone.flags).toEqual(symbol.flags);
247
+ expect(clone.originalName).toEqual(symbol.originalName);
248
+ symbol.name = "bar";
249
+ symbol.flags = OutputSymbolFlags.InstanceMemberContainer;
250
+ flushJobs();
251
+ expect(clone.name).toEqual("bar");
252
+ expect(clone.flags).toEqual(OutputSymbolFlags.InstanceMemberContainer);
253
+ });
254
+ it("works simply", () => {
255
+ const scope = new OutputScope("scope", {
256
+ binder
257
+ });
258
+ const symbol = new OutputSymbol("sym", {
259
+ binder,
260
+ scope,
261
+ flags: OutputSymbolFlags.StaticMemberContainer
262
+ });
263
+ const sourceStaticMember = new OutputSymbol("static-member", {
264
+ binder,
265
+ scope: symbol.staticMemberScope
266
+ });
267
+ const scope2 = new OutputScope("scope2", {
268
+ binder
269
+ });
270
+ const clone = symbol.copyToScope(scope2);
271
+ expect(clone.staticMemberScope.symbols.size).toBe(1);
272
+ sourceStaticMember.delete();
273
+ flushJobs();
274
+ expect(clone.staticMemberScope.symbols.size).toBe(0);
275
+ });
276
+ it("clones instance and static member scopes", () => {
277
+ const scope = new OutputScope("scope", {
278
+ binder
279
+ });
280
+ const symbol = new OutputSymbol("sym", {
281
+ binder,
282
+ scope,
283
+ flags: OutputSymbolFlags.MemberContainer
284
+ });
285
+ const sourceStaticMember = new OutputSymbol("static-member", {
286
+ binder,
287
+ scope: symbol.staticMemberScope,
288
+ flags: OutputSymbolFlags.StaticMemberContainer
289
+ });
290
+ const sourceInstanceMember = new OutputSymbol("instance-member", {
291
+ binder,
292
+ scope: symbol.instanceMemberScope
293
+ });
294
+ const scope2 = new OutputScope("scope2", {
295
+ binder
296
+ });
297
+ const clone = symbol.copyToScope(scope2);
298
+ expect(clone.instanceMemberScope).toBeDefined();
299
+ expect(clone.staticMemberScope).toBeDefined();
300
+ const clonedStaticMember = [...clone.staticMemberScope.symbols][0];
301
+ expect(clonedStaticMember.name).toBe("static-member");
302
+ expect(clonedStaticMember).toBeDefined();
303
+ expect(clonedStaticMember.flags).toBe(sourceStaticMember.flags);
304
+ const clonedInstanceMember = [...clone.instanceMemberScope.symbols][0];
305
+ expect(clonedInstanceMember.name).toBe("instance-member");
306
+ expect(clonedInstanceMember).toBeDefined();
307
+ expect(clonedInstanceMember.flags).toBe(sourceInstanceMember.flags);
308
+ expect(clonedInstanceMember.staticMemberScope).toBeUndefined();
309
+
310
+ // test reactivity
311
+ const newStaticSym = new OutputSymbol("new-sym", {
312
+ binder,
313
+ scope: symbol.staticMemberScope
314
+ });
315
+ const newInstanceSym = new OutputSymbol("new-sym", {
316
+ binder,
317
+ scope: symbol.instanceMemberScope
318
+ });
319
+ flushJobs();
320
+ expect(clone.staticMemberScope.symbolNames.has("new-sym")).toBe(true);
321
+ expect(clone.instanceMemberScope.symbolNames.has("new-sym")).toBe(true);
322
+ newStaticSym.delete();
323
+ newInstanceSym.delete();
324
+ flushJobs();
325
+ expect(clone.staticMemberScope.symbolNames.has("new-sym")).toBe(false);
326
+ expect(clone.instanceMemberScope.symbolNames.has("new-sym")).toBe(false);
327
+ });
328
+ });
329
+ describe("OutputSymbol#instantiateInto", () => {
330
+ it("copies instance members to static member scope", () => {
331
+ const scope = new OutputScope("scope", {
332
+ binder
333
+ });
334
+ const classSym = new OutputSymbol("Class", {
335
+ binder,
336
+ scope,
337
+ flags: OutputSymbolFlags.MemberContainer
338
+ });
339
+ new OutputSymbol("instance-member", {
340
+ binder,
341
+ scope: classSym.instanceMemberScope
342
+ });
343
+ new OutputSymbol("static-member", {
344
+ binder,
345
+ scope: classSym.staticMemberScope
346
+ });
347
+ const targetSym = new OutputSymbol("Target", {
348
+ binder,
349
+ scope
350
+ });
351
+ classSym.instantiateTo(targetSym);
352
+ expect(targetSym.staticMemberScope).toBeDefined();
353
+ const staticNames = targetSym.staticMemberScope.symbolNames;
354
+ expect(staticNames.size).toEqual(1);
355
+ expect(staticNames.has("instance-member")).toBe(true);
356
+ const instantiatedSym = [...targetSym.staticMemberScope.symbols][0];
357
+ expect(instantiatedSym.flags & OutputSymbolFlags.StaticMember).toBeTruthy();
358
+ });
359
+ it("is reactive to new instance members", () => {
360
+ const scope = new OutputScope("scope", {
361
+ binder
362
+ });
363
+ const classSym = new OutputSymbol("Class", {
364
+ binder,
365
+ scope,
366
+ flags: OutputSymbolFlags.MemberContainer
367
+ });
368
+ new OutputSymbol("instance-member", {
369
+ binder,
370
+ scope: classSym.instanceMemberScope
371
+ });
372
+ const targetSym = new OutputSymbol("Target", {
373
+ binder,
374
+ scope
375
+ });
376
+ classSym.instantiateTo(targetSym);
377
+ new OutputSymbol("new-instance-member", {
378
+ binder,
379
+ scope: classSym.instanceMemberScope
380
+ });
381
+ expect(targetSym.staticMemberScope.symbolNames.has("new-instance-member")).toBeDefined();
382
+ expect(targetSym.instanceMemberScope).toBeUndefined();
383
+ });
384
+ it("copies static members of instance members", () => {
385
+ const scope = new OutputScope("scope", {
386
+ binder
387
+ });
388
+ const classSym = new OutputSymbol("Class", {
389
+ binder,
390
+ scope,
391
+ flags: OutputSymbolFlags.MemberContainer
392
+ });
393
+ const instanceMemberSym = new OutputSymbol("instance-member", {
394
+ binder,
395
+ scope: classSym.instanceMemberScope,
396
+ flags: OutputSymbolFlags.StaticMemberContainer
397
+ });
398
+ new OutputSymbol("static-of-instance", {
399
+ binder,
400
+ scope: instanceMemberSym.staticMemberScope
401
+ });
402
+ const targetSym = new OutputSymbol("Target", {
403
+ binder,
404
+ scope
405
+ });
406
+ classSym.instantiateTo(targetSym);
407
+ expect(targetSym.staticMemberScope.symbolNames.has("instance-member")).toBeTruthy();
408
+ expect(targetSym.instanceMemberScope).toBeUndefined();
409
+ const instantiatedSS = [...targetSym.staticMemberScope.symbols][0];
410
+ expect(instantiatedSS.staticMemberScope).toBeDefined();
411
+ expect(instantiatedSS.staticMemberScope.symbolNames.has("static-of-instance")).toBeTruthy();
412
+
413
+ // check reactivity
414
+ const newSym = new OutputSymbol("new-static-of-instance", {
415
+ binder,
416
+ scope: instanceMemberSym.staticMemberScope
417
+ });
418
+ flushJobs();
419
+ expect(instantiatedSS.staticMemberScope.symbolNames.has("new-static-of-instance")).toBeTruthy();
420
+ newSym.delete();
421
+ flushJobs();
422
+ expect(instantiatedSS.staticMemberScope.symbolNames.has("static-member-2")).toBeFalsy();
423
+ });
424
+ it("is idempotent", () => {
425
+ const scope = new OutputScope("scope", {
426
+ binder
427
+ });
428
+ const source = new OutputSymbol("sym", {
429
+ binder,
430
+ scope,
431
+ flags: OutputSymbolFlags.InstanceMemberContainer
432
+ });
433
+ new OutputSymbol("instance-member", {
434
+ binder,
435
+ scope: source.instanceMemberScope
436
+ });
437
+ const target = new OutputSymbol("target", {
438
+ binder,
439
+ scope
440
+ });
441
+ source.instantiateTo(target);
442
+ source.instantiateTo(target);
443
+ expect(target.staticMemberScope).toBeDefined();
444
+ expect(target.staticMemberScope.symbolNames.size).toEqual(1);
445
+ expect(target.staticMemberScope.symbolNames.has("instance-member")).toBe(true);
446
+ });
447
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=resolution.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution.test.d.ts","sourceRoot":"","sources":["../../../test/symbols/resolution.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,141 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { createOutputBinder, refkey } from "../../src/index.browser.js";
3
+ import { flushJobs } from "../../src/scheduler.js";
4
+ import { OutputSymbolFlags } from "../../src/symbols/flags.js";
5
+ import { OutputSymbol } from "../../src/symbols/output-symbol.js";
6
+ import { createScopeTree } from "./utils.js";
7
+ describe("Symbol name resolution", () => {
8
+ it("resolves static symbols", () => {
9
+ const binder = createOutputBinder();
10
+ const {
11
+ symbols: {
12
+ static: staticSym
13
+ }
14
+ } = createScopeTree(binder, {
15
+ root: {
16
+ symbols: {
17
+ root: {
18
+ flags: OutputSymbolFlags.InstanceMemberContainer | OutputSymbolFlags.StaticMemberContainer,
19
+ staticMembers: {
20
+ static: {
21
+ flags: OutputSymbolFlags.StaticMember
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ });
28
+ const result = binder.resolveFQN("root.root.static");
29
+ expect(result.value).toEqual(staticSym);
30
+ });
31
+ it("resolves static symbols that are added later", () => {
32
+ const binder = createOutputBinder();
33
+ const result = binder.resolveFQN("root.root.static");
34
+ expect(result.value).toBeUndefined();
35
+ const {
36
+ symbols: {
37
+ static: staticSym
38
+ }
39
+ } = createScopeTree(binder, {
40
+ root: {
41
+ symbols: {
42
+ root: {
43
+ flags: OutputSymbolFlags.InstanceMemberContainer | OutputSymbolFlags.StaticMemberContainer,
44
+ staticMembers: {
45
+ static: {
46
+ flags: OutputSymbolFlags.StaticMember
47
+ }
48
+ }
49
+ }
50
+ }
51
+ }
52
+ });
53
+ expect(result.value).toEqual(staticSym);
54
+ });
55
+ it("resolves instance symbols", () => {
56
+ const binder = createOutputBinder();
57
+ const {
58
+ symbols: {
59
+ instance
60
+ }
61
+ } = createScopeTree(binder, {
62
+ root: {
63
+ symbols: {
64
+ root: {
65
+ flags: OutputSymbolFlags.InstanceMemberContainer,
66
+ instanceMembers: {
67
+ instance: {
68
+ flags: OutputSymbolFlags.InstanceMember
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ });
75
+ const result = binder.resolveFQN("root.root#instance");
76
+ expect(result.value).toEqual(instance);
77
+ });
78
+ it("resolves instance symbols that are added later", () => {
79
+ const binder = createOutputBinder();
80
+ const result = binder.resolveFQN("root.root#instance");
81
+ expect(result.value).toBeUndefined();
82
+ const {
83
+ symbols: {
84
+ instance
85
+ }
86
+ } = createScopeTree(binder, {
87
+ root: {
88
+ symbols: {
89
+ root: {
90
+ flags: OutputSymbolFlags.InstanceMemberContainer,
91
+ instanceMembers: {
92
+ instance: {
93
+ flags: OutputSymbolFlags.InstanceMember
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ });
100
+ expect(result.value).toEqual(instance);
101
+ });
102
+ });
103
+ describe("refkey resolution", () => {
104
+ it("resolves existing symbols by refkey", () => {
105
+ const key = refkey();
106
+ const binder = createOutputBinder();
107
+ const sym = new OutputSymbol("foo", {
108
+ binder,
109
+ scope: binder.globalScope,
110
+ refkeys: [key]
111
+ });
112
+ const resolvedSym = binder.resolveDeclarationByKey(undefined, undefined, key);
113
+ expect(resolvedSym.value?.targetDeclaration).toBe(sym);
114
+ });
115
+ it("resolves symbols by refkey when symbol is added later", () => {
116
+ const key = refkey();
117
+ const binder = createOutputBinder();
118
+ const resolvedSym = binder.resolveDeclarationByKey(undefined, undefined, key);
119
+ const sym = new OutputSymbol("foo", {
120
+ binder,
121
+ scope: binder.globalScope,
122
+ refkeys: [key]
123
+ });
124
+ expect(resolvedSym.value?.targetDeclaration).toBe(sym);
125
+ });
126
+ it("handles deleted symbols by updating resolutions", () => {
127
+ const key = refkey();
128
+ const binder = createOutputBinder();
129
+ const resolvedSym = binder.resolveDeclarationByKey(undefined, undefined, key);
130
+ const sym = new OutputSymbol("foo", {
131
+ binder,
132
+ scope: binder.globalScope,
133
+ refkeys: [key]
134
+ });
135
+ flushJobs();
136
+ expect(resolvedSym.value?.targetDeclaration).toBe(sym);
137
+ sym.delete();
138
+ flushJobs();
139
+ expect(resolvedSym.value).toBe(undefined);
140
+ });
141
+ });
@@ -0,0 +1,25 @@
1
+ import { Binder } from "../../src/index.browser.js";
2
+ import { Refkey } from "../../src/refkey.js";
3
+ import { OutputScopeFlags, OutputSymbolFlags } from "../../src/symbols/flags.js";
4
+ import { OutputScope } from "../../src/symbols/output-scope.js";
5
+ import { OutputSymbol } from "../../src/symbols/output-symbol.js";
6
+ type ScopeRecords = Record<string, ScopeDescriptor>;
7
+ type SymbolRecords = Record<string, SymbolDescriptor>;
8
+ interface ScopeDescriptor {
9
+ flags?: OutputScopeFlags;
10
+ scopes?: ScopeRecords;
11
+ symbols: SymbolRecords;
12
+ }
13
+ interface SymbolDescriptor {
14
+ refkey?: Refkey;
15
+ flags?: OutputSymbolFlags;
16
+ instanceMembers?: SymbolRecords;
17
+ staticMembers?: SymbolRecords;
18
+ }
19
+ interface ScopeTreeResult {
20
+ symbols: Record<string, OutputSymbol>;
21
+ scopes: Record<string, OutputScope>;
22
+ }
23
+ export declare function createScopeTree(binder: Binder, tree: ScopeRecords): ScopeTreeResult;
24
+ export {};
25
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../test/symbols/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,MAAM,EAAU,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AACpD,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAEtD,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,eAAe,CAAC,EAAE,aAAa,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC;AACD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,YAAY,GACjB,eAAe,CA4DjB"}
@@ -0,0 +1,47 @@
1
+ import { refkey } from "../../src/refkey.js";
2
+ import { OutputSymbolFlags } from "../../src/symbols/flags.js";
3
+ import { OutputScope } from "../../src/symbols/output-scope.js";
4
+ import { OutputSymbol } from "../../src/symbols/output-symbol.js";
5
+ export function createScopeTree(binder, tree) {
6
+ const createdItems = {
7
+ symbols: {},
8
+ scopes: {}
9
+ };
10
+ for (const [name, desc] of Object.entries(tree)) {
11
+ createScope(name, desc);
12
+ }
13
+ return createdItems;
14
+ function createScope(name, descriptor, parent = binder.globalScope) {
15
+ const scope = new OutputScope(name, {
16
+ binder,
17
+ parent,
18
+ flags: descriptor.flags
19
+ });
20
+ createdItems.scopes[name] = scope;
21
+ for (const [name, desc] of Object.entries(descriptor.symbols)) {
22
+ createSymbol(name, desc, scope);
23
+ }
24
+ for (const [name, desc] of Object.entries(descriptor.scopes ?? {})) {
25
+ createScope(name, desc, scope);
26
+ }
27
+ }
28
+ function createSymbol(name, descriptor, parent) {
29
+ const symbol = new OutputSymbol(name, {
30
+ binder,
31
+ scope: parent,
32
+ refkeys: [descriptor.refkey ?? refkey()],
33
+ flags: descriptor.flags ?? OutputSymbolFlags.None
34
+ });
35
+ createdItems.symbols[name] = symbol;
36
+ if (descriptor.instanceMembers) {
37
+ for (const [name, desc] of Object.entries(descriptor.instanceMembers)) {
38
+ createSymbol(name, desc, symbol.instanceMemberScope);
39
+ }
40
+ }
41
+ if (descriptor.staticMembers) {
42
+ for (const [name, desc] of Object.entries(descriptor.staticMembers)) {
43
+ createSymbol(name, desc, symbol.staticMemberScope);
44
+ }
45
+ }
46
+ }
47
+ }
@@ -1,2 +1,17 @@
1
+ import "vitest";
2
+ interface ToRenderToRenderOptions {
3
+ printWidth?: number;
4
+ tabWidth?: number;
5
+ useTabs?: boolean;
6
+ }
7
+ interface CustomMatchers<R = unknown> {
8
+ toRenderTo: (str: string, options?: ToRenderToRenderOptions) => R;
9
+ }
10
+ declare module "vitest" {
11
+ interface Assertion<T = any> extends CustomMatchers<T> {
12
+ }
13
+ interface AsymmetricMatchersContaining extends CustomMatchers {
14
+ }
15
+ }
1
16
  export {};
2
17
  //# sourceMappingURL=extend-expect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extend-expect.d.ts","sourceRoot":"","sources":["../../testing/extend-expect.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"extend-expect.d.ts","sourceRoot":"","sources":["../../testing/extend-expect.ts"],"names":[],"mappings":"AA+BA,OAAO,QAAQ,CAAC;AAEhB,UAAU,uBAAuB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AACD,UAAU,cAAc,CAAC,CAAC,GAAG,OAAO;IAClC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB,KAAK,CAAC,CAAC;CACnE;AAED,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,SAAS,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;KAAG;IACzD,UAAU,4BAA6B,SAAQ,cAAc;KAAG;CACjE"}