@alloy-js/core 0.20.0-dev.4 → 0.20.0-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. package/dist/src/binder.d.ts +74 -38
  2. package/dist/src/binder.d.ts.map +1 -1
  3. package/dist/src/binder.js +235 -173
  4. package/dist/src/binder.js.map +1 -0
  5. package/dist/src/code.js +2 -1
  6. package/dist/src/code.js.map +1 -0
  7. package/dist/src/components/AppendFile.js +2 -1
  8. package/dist/src/components/AppendFile.js.map +1 -0
  9. package/dist/src/components/Block.js +2 -1
  10. package/dist/src/components/Block.js.map +1 -0
  11. package/dist/src/components/CopyFile.js +2 -1
  12. package/dist/src/components/CopyFile.js.map +1 -0
  13. package/dist/src/components/Declaration.d.ts +2 -2
  14. package/dist/src/components/Declaration.d.ts.map +1 -1
  15. package/dist/src/components/Declaration.js +10 -3
  16. package/dist/src/components/Declaration.js.map +1 -0
  17. package/dist/src/components/For.js +2 -1
  18. package/dist/src/components/For.js.map +1 -0
  19. package/dist/src/components/Indent.js +2 -1
  20. package/dist/src/components/Indent.js.map +1 -0
  21. package/dist/src/components/List.js +2 -1
  22. package/dist/src/components/List.js.map +1 -0
  23. package/dist/src/components/MemberDeclaration.d.ts +2 -2
  24. package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
  25. package/dist/src/components/MemberDeclaration.js +11 -6
  26. package/dist/src/components/MemberDeclaration.js.map +1 -0
  27. package/dist/src/components/MemberName.js +2 -1
  28. package/dist/src/components/MemberName.js.map +1 -0
  29. package/dist/src/components/MemberScope.d.ts +30 -13
  30. package/dist/src/components/MemberScope.d.ts.map +1 -1
  31. package/dist/src/components/MemberScope.js +39 -16
  32. package/dist/src/components/MemberScope.js.map +1 -0
  33. package/dist/src/components/Name.js +2 -1
  34. package/dist/src/components/Name.js.map +1 -0
  35. package/dist/src/components/Output.d.ts.map +1 -1
  36. package/dist/src/components/Output.js +4 -6
  37. package/dist/src/components/Output.js.map +1 -0
  38. package/dist/src/components/Prose.js +2 -1
  39. package/dist/src/components/Prose.js.map +1 -0
  40. package/dist/src/components/ReferenceOrContent.d.ts +1 -1
  41. package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
  42. package/dist/src/components/ReferenceOrContent.js +2 -1
  43. package/dist/src/components/ReferenceOrContent.js.map +1 -0
  44. package/dist/src/components/Scope.d.ts +5 -5
  45. package/dist/src/components/Scope.d.ts.map +1 -1
  46. package/dist/src/components/Scope.js +11 -6
  47. package/dist/src/components/Scope.js.map +1 -0
  48. package/dist/src/components/Show.js +2 -1
  49. package/dist/src/components/Show.js.map +1 -0
  50. package/dist/src/components/SourceDirectory.js +2 -1
  51. package/dist/src/components/SourceDirectory.js.map +1 -0
  52. package/dist/src/components/SourceFile.js +2 -1
  53. package/dist/src/components/SourceFile.js.map +1 -0
  54. package/dist/src/components/StatementList.js +2 -1
  55. package/dist/src/components/StatementList.js.map +1 -0
  56. package/dist/src/components/Switch.js +2 -1
  57. package/dist/src/components/Switch.js.map +1 -0
  58. package/dist/src/components/TemplateFile.js +2 -1
  59. package/dist/src/components/TemplateFile.js.map +1 -0
  60. package/dist/src/components/UpdateFile.js +2 -1
  61. package/dist/src/components/UpdateFile.js.map +1 -0
  62. package/dist/src/components/Wrap.js +2 -1
  63. package/dist/src/components/Wrap.js.map +1 -0
  64. package/dist/src/components/index.js +2 -1
  65. package/dist/src/components/index.js.map +1 -0
  66. package/dist/src/components/stc/index.js +2 -1
  67. package/dist/src/components/stc/index.js.map +1 -0
  68. package/dist/src/components/stc/sti.js +2 -1
  69. package/dist/src/components/stc/sti.js.map +1 -0
  70. package/dist/src/context/assignment.js +2 -1
  71. package/dist/src/context/assignment.js.map +1 -0
  72. package/dist/src/context/binder.js +2 -1
  73. package/dist/src/context/binder.js.map +1 -0
  74. package/dist/src/context/declaration.js +2 -1
  75. package/dist/src/context/declaration.js.map +1 -0
  76. package/dist/src/context/index.js +2 -1
  77. package/dist/src/context/index.js.map +1 -0
  78. package/dist/src/context/member-declaration.js +2 -1
  79. package/dist/src/context/member-declaration.js.map +1 -0
  80. package/dist/src/context/member-scope.d.ts +7 -8
  81. package/dist/src/context/member-scope.d.ts.map +1 -1
  82. package/dist/src/context/member-scope.js +7 -6
  83. package/dist/src/context/member-scope.js.map +1 -0
  84. package/dist/src/context/name-policy.d.ts.map +1 -1
  85. package/dist/src/context/name-policy.js +5 -1
  86. package/dist/src/context/name-policy.js.map +1 -0
  87. package/dist/src/context/scope.d.ts +1 -0
  88. package/dist/src/context/scope.d.ts.map +1 -1
  89. package/dist/src/context/scope.js +9 -1
  90. package/dist/src/context/scope.js.map +1 -0
  91. package/dist/src/context/source-directory.js +2 -1
  92. package/dist/src/context/source-directory.js.map +1 -0
  93. package/dist/src/context/source-file.js +2 -1
  94. package/dist/src/context/source-file.js.map +1 -0
  95. package/dist/src/context.js +2 -1
  96. package/dist/src/context.js.map +1 -0
  97. package/dist/src/debug.js +2 -1
  98. package/dist/src/debug.js.map +1 -0
  99. package/dist/src/host/alloy-host.browser.js +2 -1
  100. package/dist/src/host/alloy-host.browser.js.map +1 -0
  101. package/dist/src/host/alloy-host.js +2 -1
  102. package/dist/src/host/alloy-host.js.map +1 -0
  103. package/dist/src/host/interface.js +2 -1
  104. package/dist/src/host/interface.js.map +1 -0
  105. package/dist/src/index.browser.js +2 -1
  106. package/dist/src/index.browser.js.map +1 -0
  107. package/dist/src/index.js +2 -1
  108. package/dist/src/index.js.map +1 -0
  109. package/dist/src/inspect.browser.d.ts +5 -0
  110. package/dist/src/inspect.browser.d.ts.map +1 -0
  111. package/dist/src/inspect.browser.js +6 -0
  112. package/dist/src/inspect.browser.js.map +1 -0
  113. package/dist/src/inspect.d.ts +2 -0
  114. package/dist/src/inspect.d.ts.map +1 -0
  115. package/dist/src/inspect.js +2 -0
  116. package/dist/src/inspect.js.map +1 -0
  117. package/dist/src/jsx-runtime.js +2 -1
  118. package/dist/src/jsx-runtime.js.map +1 -0
  119. package/dist/src/name-policy.d.ts +11 -0
  120. package/dist/src/name-policy.d.ts.map +1 -1
  121. package/dist/src/name-policy.js +5 -1
  122. package/dist/src/name-policy.js.map +1 -0
  123. package/dist/src/props-combinators.js +2 -1
  124. package/dist/src/props-combinators.js.map +1 -0
  125. package/dist/src/reactive-union-set.d.ts.map +1 -1
  126. package/dist/src/reactive-union-set.js +14 -9
  127. package/dist/src/reactive-union-set.js.map +1 -0
  128. package/dist/src/reactivity.js +2 -1
  129. package/dist/src/reactivity.js.map +1 -0
  130. package/dist/src/refkey.d.ts +39 -3
  131. package/dist/src/refkey.d.ts.map +1 -1
  132. package/dist/src/refkey.js +65 -10
  133. package/dist/src/refkey.js.map +1 -0
  134. package/dist/src/render.js +2 -1
  135. package/dist/src/render.js.map +1 -0
  136. package/dist/src/resource.js +2 -1
  137. package/dist/src/resource.js.map +1 -0
  138. package/dist/src/runtime/component.js +2 -1
  139. package/dist/src/runtime/component.js.map +1 -0
  140. package/dist/src/runtime/intrinsic.js +2 -1
  141. package/dist/src/runtime/intrinsic.js.map +1 -0
  142. package/dist/src/scheduler.js +2 -1
  143. package/dist/src/scheduler.js.map +1 -0
  144. package/dist/src/stc.js +2 -1
  145. package/dist/src/stc.js.map +1 -0
  146. package/dist/src/sti.js +2 -1
  147. package/dist/src/sti.js.map +1 -0
  148. package/dist/src/symbols/basic-scope.d.ts +14 -0
  149. package/dist/src/symbols/basic-scope.d.ts.map +1 -0
  150. package/dist/src/symbols/basic-scope.js +21 -0
  151. package/dist/src/symbols/basic-scope.js.map +1 -0
  152. package/dist/src/symbols/basic-symbol.d.ts +19 -0
  153. package/dist/src/symbols/basic-symbol.d.ts.map +1 -0
  154. package/dist/src/symbols/basic-symbol.js +29 -0
  155. package/dist/src/symbols/basic-symbol.js.map +1 -0
  156. package/dist/src/symbols/index.d.ts +3 -1
  157. package/dist/src/symbols/index.d.ts.map +1 -1
  158. package/dist/src/symbols/index.js +5 -2
  159. package/dist/src/symbols/index.js.map +1 -0
  160. package/dist/src/symbols/output-scope.d.ts +70 -41
  161. package/dist/src/symbols/output-scope.d.ts.map +1 -1
  162. package/dist/src/symbols/output-scope.js +100 -131
  163. package/dist/src/symbols/output-scope.js.map +1 -0
  164. package/dist/src/symbols/output-space.d.ts +25 -0
  165. package/dist/src/symbols/output-space.d.ts.map +1 -0
  166. package/dist/src/symbols/output-space.js +36 -0
  167. package/dist/src/symbols/output-space.js.map +1 -0
  168. package/dist/src/symbols/output-symbol.d.ts +213 -37
  169. package/dist/src/symbols/output-symbol.d.ts.map +1 -1
  170. package/dist/src/symbols/output-symbol.js +325 -204
  171. package/dist/src/symbols/output-symbol.js.map +1 -0
  172. package/dist/src/symbols/symbol-flow.d.ts +1 -1
  173. package/dist/src/symbols/symbol-flow.d.ts.map +1 -1
  174. package/dist/src/symbols/symbol-flow.js +24 -8
  175. package/dist/src/symbols/symbol-flow.js.map +1 -0
  176. package/dist/src/symbols/symbol-slot.d.ts +27 -9
  177. package/dist/src/symbols/symbol-slot.d.ts.map +1 -1
  178. package/dist/src/symbols/symbol-slot.js +22 -5
  179. package/dist/src/symbols/symbol-slot.js.map +1 -0
  180. package/dist/src/symbols/symbol-table.d.ts +19 -8
  181. package/dist/src/symbols/symbol-table.d.ts.map +1 -1
  182. package/dist/src/symbols/symbol-table.js +67 -17
  183. package/dist/src/symbols/symbol-table.js.map +1 -0
  184. package/dist/src/tap.js +2 -1
  185. package/dist/src/tap.js.map +1 -0
  186. package/dist/src/tracer.d.ts +15 -3
  187. package/dist/src/tracer.d.ts.map +1 -1
  188. package/dist/src/tracer.js +41 -64
  189. package/dist/src/tracer.js.map +1 -0
  190. package/dist/src/utils.js +2 -1
  191. package/dist/src/utils.js.map +1 -0
  192. package/dist/src/write-output.js +2 -1
  193. package/dist/src/write-output.js.map +1 -0
  194. package/dist/test/browser-build.test.js +2 -1
  195. package/dist/test/browser-build.test.js.map +1 -0
  196. package/dist/test/children.test.js +2 -1
  197. package/dist/test/children.test.js.map +1 -0
  198. package/dist/test/components/append-file.test.js +2 -1
  199. package/dist/test/components/append-file.test.js.map +1 -0
  200. package/dist/test/components/block.test.js +2 -1
  201. package/dist/test/components/block.test.js.map +1 -0
  202. package/dist/test/components/copy-file.test.js +2 -1
  203. package/dist/test/components/copy-file.test.js.map +1 -0
  204. package/dist/test/components/declaration.test.js +11 -15
  205. package/dist/test/components/declaration.test.js.map +1 -0
  206. package/dist/test/components/list.test.js +2 -1
  207. package/dist/test/components/list.test.js.map +1 -0
  208. package/dist/test/components/prose.test.js +2 -1
  209. package/dist/test/components/prose.test.js.map +1 -0
  210. package/dist/test/components/reference-or-content.test.js +4 -3
  211. package/dist/test/components/reference-or-content.test.js.map +1 -0
  212. package/dist/test/components/source-file.test.js +2 -1
  213. package/dist/test/components/source-file.test.js.map +1 -0
  214. package/dist/test/components/template-file.test.js +2 -1
  215. package/dist/test/components/template-file.test.js.map +1 -0
  216. package/dist/test/components/update-file.test.js +2 -1
  217. package/dist/test/components/update-file.test.js.map +1 -0
  218. package/dist/test/components/wrap.test.js +2 -1
  219. package/dist/test/components/wrap.test.js.map +1 -0
  220. package/dist/test/control-flow/for.test.js +2 -1
  221. package/dist/test/control-flow/for.test.js.map +1 -0
  222. package/dist/test/control-flow/match.test.js +2 -1
  223. package/dist/test/control-flow/match.test.js.map +1 -0
  224. package/dist/test/control-flow/show.test.js +2 -1
  225. package/dist/test/control-flow/show.test.js.map +1 -0
  226. package/dist/test/name-policy.test.js +2 -1
  227. package/dist/test/name-policy.test.js.map +1 -0
  228. package/dist/test/props-with-defaults.test.js +2 -1
  229. package/dist/test/props-with-defaults.test.js.map +1 -0
  230. package/dist/test/reactive-union-set.test.js +2 -1
  231. package/dist/test/reactive-union-set.test.js.map +1 -0
  232. package/dist/test/reactivity/circular-reactives.test.js +2 -1
  233. package/dist/test/reactivity/circular-reactives.test.js.map +1 -0
  234. package/dist/test/reactivity/cleanup.test.js +2 -1
  235. package/dist/test/reactivity/cleanup.test.js.map +1 -0
  236. package/dist/test/reactivity/memo.test.js +2 -1
  237. package/dist/test/reactivity/memo.test.js.map +1 -0
  238. package/dist/test/reactivity/ref-rendering.test.js +2 -1
  239. package/dist/test/reactivity/ref-rendering.test.js.map +1 -0
  240. package/dist/test/reactivity/test.test.js +2 -1
  241. package/dist/test/reactivity/test.test.js.map +1 -0
  242. package/dist/test/reactivity/untrack.test.js +2 -1
  243. package/dist/test/reactivity/untrack.test.js.map +1 -0
  244. package/dist/test/refkey.test.js +2 -1
  245. package/dist/test/refkey.test.js.map +1 -0
  246. package/dist/test/rendering/basic.test.js +2 -1
  247. package/dist/test/rendering/basic.test.js.map +1 -0
  248. package/dist/test/rendering/code.test.js +2 -1
  249. package/dist/test/rendering/code.test.js.map +1 -0
  250. package/dist/test/rendering/formatting.test.js +2 -1
  251. package/dist/test/rendering/formatting.test.js.map +1 -0
  252. package/dist/test/rendering/indent.test.js +2 -1
  253. package/dist/test/rendering/indent.test.js.map +1 -0
  254. package/dist/test/rendering/memoization.test.js +2 -1
  255. package/dist/test/rendering/memoization.test.js.map +1 -0
  256. package/dist/test/rendering/refkeys.test.js +2 -1
  257. package/dist/test/rendering/refkeys.test.js.map +1 -0
  258. package/dist/test/split-props.test.js +2 -1
  259. package/dist/test/split-props.test.js.map +1 -0
  260. package/dist/test/stc.test.js +2 -1
  261. package/dist/test/stc.test.js.map +1 -0
  262. package/dist/test/symbols/output-scope.test.js +34 -198
  263. package/dist/test/symbols/output-scope.test.js.map +1 -0
  264. package/dist/test/symbols/output-symbol.test.js +141 -386
  265. package/dist/test/symbols/output-symbol.test.js.map +1 -0
  266. package/dist/test/symbols/resolution.test.js +433 -115
  267. package/dist/test/symbols/resolution.test.js.map +1 -0
  268. package/dist/test/symbols/symbol-table.test.d.ts +2 -0
  269. package/dist/test/symbols/symbol-table.test.d.ts.map +1 -0
  270. package/dist/test/symbols/symbol-table.test.js +15 -0
  271. package/dist/test/symbols/symbol-table.test.js.map +1 -0
  272. package/dist/test/symbols/utils.d.ts +10 -24
  273. package/dist/test/symbols/utils.d.ts.map +1 -1
  274. package/dist/test/symbols/utils.js +25 -46
  275. package/dist/test/symbols/utils.js.map +1 -0
  276. package/dist/test/utils.test.js +2 -1
  277. package/dist/test/utils.test.js.map +1 -0
  278. package/dist/testing/extend-expect.js +2 -1
  279. package/dist/testing/extend-expect.js.map +1 -0
  280. package/dist/testing/extend-expect.test.js +2 -1
  281. package/dist/testing/extend-expect.test.js.map +1 -0
  282. package/dist/testing/index.js +2 -1
  283. package/dist/testing/index.js.map +1 -0
  284. package/dist/testing/render.js +2 -1
  285. package/dist/testing/render.js.map +1 -0
  286. package/dist/testing/vitest.d.js +2 -1
  287. package/dist/testing/vitest.d.js.map +1 -0
  288. package/dist/tsconfig.tsbuildinfo +1 -1
  289. package/package.json +5 -3
  290. package/src/binder.ts +368 -273
  291. package/src/components/Declaration.tsx +13 -3
  292. package/src/components/MemberDeclaration.tsx +15 -8
  293. package/src/components/MemberScope.tsx +61 -20
  294. package/src/components/Output.tsx +0 -4
  295. package/src/components/Scope.tsx +16 -9
  296. package/src/context/member-scope.ts +10 -10
  297. package/src/context/name-policy.ts +3 -0
  298. package/src/context/scope.ts +9 -0
  299. package/src/inspect.browser.ts +6 -0
  300. package/src/inspect.ts +1 -0
  301. package/src/name-policy.ts +14 -0
  302. package/src/reactive-union-set.ts +14 -8
  303. package/src/refkey.ts +106 -14
  304. package/src/symbols/basic-scope.ts +23 -0
  305. package/src/symbols/basic-symbol.ts +32 -0
  306. package/src/symbols/index.ts +3 -1
  307. package/src/symbols/output-scope.ts +131 -170
  308. package/src/symbols/output-space.ts +49 -0
  309. package/src/symbols/output-symbol.ts +434 -258
  310. package/src/symbols/symbol-flow.ts +38 -9
  311. package/src/symbols/symbol-slot.tsx +46 -8
  312. package/src/symbols/symbol-table.ts +95 -21
  313. package/src/tracer.ts +53 -83
  314. package/temp/api.json +7009 -4461
  315. package/test/components/declaration.test.tsx +6 -19
  316. package/test/components/reference-or-content.test.tsx +2 -2
  317. package/test/symbols/output-scope.test.ts +33 -125
  318. package/test/symbols/output-symbol.test.ts +128 -348
  319. package/test/symbols/resolution.test.ts +530 -117
  320. package/test/symbols/symbol-table.test.ts +15 -0
  321. package/test/symbols/utils.ts +38 -74
  322. package/tsdoc.json +4 -0
  323. package/dist/src/slot.d.ts +0 -15
  324. package/dist/src/slot.d.ts.map +0 -1
  325. package/dist/src/slot.js +0 -50
  326. package/dist/src/symbols/flags.d.ts +0 -70
  327. package/dist/src/symbols/flags.d.ts.map +0 -1
  328. package/dist/src/symbols/flags.js +0 -72
  329. package/dist/test/components/slot.test.d.ts +0 -2
  330. package/dist/test/components/slot.test.d.ts.map +0 -1
  331. package/dist/test/components/slot.test.js +0 -134
  332. package/src/slot.ts +0 -89
  333. package/src/symbols/flags.ts +0 -82
  334. 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 { useMemberScope } from "../context/member-scope.js";
14
- import { useScope } from "../context/scope.js";
15
- import { isRefkey, refkey, type Refkey } from "../refkey.js";
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 { OutputScopeFlags, OutputSymbolFlags } from "./flags.js";
25
- import { OutputScope } from "./output-scope.js";
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
- scope?: OutputScope;
30
- flags?: OutputSymbolFlags;
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
- #name: string;
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 = 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
- #flags: OutputSymbolFlags;
76
- get flags() {
77
- track(this, TrackOpTypes.GET, "flags");
78
- return this.#flags;
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
- this.#flags = flags;
88
- trigger(this, TriggerOpTypes.SET, "flags", flags, old);
173
+ #ignoreNameConflict: boolean = false;
89
174
 
90
- this.#createInstanceMemberScope();
91
- this.#createStaticMemberScope();
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
- #scope: OutputScope;
95
- get scope() {
96
- track(this, TrackOpTypes.GET, "scope");
97
- return this.#scope;
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
- set scope(scope: OutputScope) {
101
- const old = this.#scope;
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
- if (old === scope) {
104
- return;
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.#handleNewScope(scope, old);
213
+ if (this.spaces.length === 0) {
214
+ return undefined;
215
+ }
108
216
 
109
- this.#scope = scope;
217
+ return (this.spaces[0] as OutputDeclarationSpace).scope;
218
+ }
110
219
 
111
- trigger(this, TriggerOpTypes.SET, "scope", scope, old);
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
- #handleNewScope(newScope: OutputScope, oldScope?: OutputScope) {
115
- if (oldScope) {
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 (!newScope) {
234
+ if (old === spaces) {
121
235
  return;
122
236
  }
123
237
 
124
- newScope.symbols.add(this);
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
- if (newScope.flags & OutputScopeFlags.InstanceMemberScope) {
127
- this.flags |= OutputSymbolFlags.InstanceMember;
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 (newScope.flags & OutputScopeFlags.StaticMemberScope) {
131
- this.flags |= OutputSymbolFlags.StaticMember;
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
- #createInstanceMemberScope() {
171
- if (
172
- this.#instanceMemberScope ||
173
- !(this.#flags & OutputSymbolFlags.InstanceMemberContainer)
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
- this.#instanceMemberScope = new OutputScope(
179
- `${this.name} instance members`,
180
- {
181
- binder: this.#binder,
182
- owner: this,
183
- flags: OutputScopeFlags.InstanceMemberScope,
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
- * Create an output scope to hold member symbols. By default this just creates
197
- * an OutputScope, but can be subclassed to build scope subtypes when needed.
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
- protected createMemberScope(
200
- name: string,
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
- #staticMemberScope?: OutputScope;
214
- get staticMemberScope() {
215
- track(this, TrackOpTypes.GET, "staticMemberScope");
216
- return this.#staticMemberScope;
335
+ copyToSpace(space: OutputSpace) {
336
+ const copy = this.copy();
337
+ copy.spaces = space;
338
+ return copy;
217
339
  }
218
340
 
219
- #createStaticMemberScope() {
220
- if (
221
- this.#staticMemberScope ||
222
- !(this.#flags & OutputSymbolFlags.StaticMemberContainer)
223
- ) {
224
- return;
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
- this.#staticMemberScope = new OutputScope(`${this.name} static members`, {
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
- #metadata: Record<string, unknown>;
242
- get metadata() {
243
- return this.#metadata;
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
- * Tell \@vue/reactivity that this symbol should never be wrapped in a reactive
248
- * proxy.
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(): OutputSymbol | undefined {
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(name: string, options: OutputSymbolOptions = {}) {
466
+ constructor(
467
+ name: string | Namekey,
468
+ spaces: OutputSpace[] | OutputSpace | undefined,
469
+ options: OutputSymbolOptions = {},
470
+ ) {
253
471
  this.#binder = options.binder ?? useBinder();
254
- this.#name = name;
255
- this.#originalName = name;
256
- this.#id = symbolCount++;
257
- this.#flags = options.flags ?? OutputSymbolFlags.None;
258
- this.#scope = options.scope ?? (this.#defaultScope() as OutputScope);
259
- this.#aliasTarget = options.aliasTarget;
260
- if (this.#aliasTarget) {
261
- this.#flags |= OutputSymbolFlags.Alias;
262
- this.#flags &= ~(
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
- this.#refkeys = shallowReactive(
267
- Array.isArray(options.refkeys) ? options.refkeys
268
- : isRefkey(options.refkeys) ? [options.refkeys]
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.#createInstanceMemberScope();
273
- this.#createStaticMemberScope();
274
- this.#handleNewScope(this.#scope);
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.#scope) {
286
- this.#scope.symbols.delete(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
- * Takes the instance members or static members on this symbol and creates
294
- * corresponding static members on the target symbol. Instance or static
295
- * members of instantiated symbols are copied. The refkey of any instantiated
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
- instantiateTo(targetSymbol: OutputSymbol): void {
546
+ moveMembersTo(targetSymbol: OutputSymbol): void {
300
547
  if (this.#aliasTarget) {
301
- return this.#aliasTarget.instantiateTo(targetSymbol);
548
+ return this.#aliasTarget.moveMembersTo(targetSymbol);
302
549
  }
303
550
 
304
- trace(TracePhase.symbol.instantiate, () => {
305
- return `${formatSymbolName(this)} -> ${formatSymbolName(targetSymbol)}`;
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
- #instantiationRk(base: OutputSymbol, member: OutputSymbol) {
328
- const instantiationRks = [];
329
- for (const baseRk of base.refkeys) {
330
- for (const targetRk of member.refkeys) {
331
- instantiationRks.push(refkey(baseRk, targetRk));
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
- if (this.instanceMemberScope) {
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
- * Move member symbols from this transient symbol to the target symbol.
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
- moveTo(targetSymbol: OutputSymbol): void {
574
+ copyMembersTo(targetSymbol: OutputSymbol): void {
364
575
  if (this.#aliasTarget) {
365
- return this.#aliasTarget.moveTo(targetSymbol);
576
+ return this.#aliasTarget.copyMembersTo(targetSymbol);
366
577
  }
367
578
 
368
- if (!(this.flags & OutputSymbolFlags.Transient)) {
369
- throw new Error("Can only move members from transient symbols");
370
- }
371
- if (this.staticMemberScope) {
372
- targetSymbol.flags |= OutputSymbolFlags.StaticMemberContainer;
373
- targetSymbol.staticMemberScope!.moveSymbolsFrom(this.staticMemberScope);
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
- if (this.instanceMemberScope) {
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
- copyToScope(newScope: OutputScope, baseSymbol?: OutputSymbol): OutputSymbol {
398
- if (this.#aliasTarget) {
399
- return this.#aliasTarget.copyToScope(newScope, baseSymbol);
400
- }
401
- trace(TracePhase.symbol.clone, () => {
402
- return `${formatSymbolName(this)} -> ${formatScopeName(newScope)}`;
403
- });
404
- const clone = new OutputSymbol(this.#name, {
405
- binder: this.#binder,
406
- scope: newScope,
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
- if (this.instanceMemberScope) {
413
- clone.#instanceMemberScope = this.instanceMemberScope.clone({
414
- owner: clone,
415
- });
416
- }
615
+ protected initializeCopy(copy: OutputSymbol) {
616
+ for (const sourceSpace of this.memberSpaces) {
617
+ const targetSpace = copy.memberSpaceFor(sourceSpace.key);
417
618
 
418
- if (this.staticMemberScope) {
419
- clone.#staticMemberScope = this.staticMemberScope.clone({ owner: clone });
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) => (clone.name = 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
- #defaultScope() {
435
- if ((this.#flags & OutputSymbolFlags.Member) === 0) {
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
  }