dsh-ptc-plus 0.3.2 → 0.4.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 (206) hide show
  1. package/README.en.md +63 -80
  2. package/README.md +63 -80
  3. package/assets/ptc-plus-bindings-en.png +0 -0
  4. package/assets/ptc-plus-bindings-zh.png +0 -0
  5. package/assets/ptc-plus-repair-en.png +0 -0
  6. package/assets/ptc-plus-repair-zh.png +0 -0
  7. package/assets/ptc-plus-repl-workspace-en.png +0 -0
  8. package/assets/ptc-plus-repl-workspace-zh.png +0 -0
  9. package/assets/ptc-plus-settings-en.png +0 -0
  10. package/assets/ptc-plus-settings-zh.png +0 -0
  11. package/client.js +30827 -742
  12. package/compiler-amaro.cjs +5 -0
  13. package/compiler-amaro.cjs.map +6 -0
  14. package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
  15. package/compiler-assets.json +3 -0
  16. package/compiler-core.cjs +556 -0
  17. package/compiler-core.cjs.map +6 -0
  18. package/compiler-platform.cjs +2 -0
  19. package/compiler-platform.cjs.map +6 -0
  20. package/compiler-typescript.cjs +388 -0
  21. package/compiler-typescript.cjs.map +6 -0
  22. package/docs/README.md +7 -0
  23. package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
  24. package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +5 -3
  25. package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +1 -1
  26. package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
  27. package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
  28. package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
  29. package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
  30. package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +3 -1
  31. package/docs/adr/0014-persist-cell-rewrite-policy.md +6 -2
  32. package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
  33. package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
  34. package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
  35. package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
  36. package/docs/adr/0019-plugin-settings-and-kill-switch.md +5 -3
  37. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
  38. package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +12 -0
  39. package/docs/adr/0023-global-user-bindings.md +104 -0
  40. package/docs/adr/0024-repl-console-observation.md +33 -0
  41. package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
  42. package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
  43. package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
  44. package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
  45. package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
  46. package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
  47. package/docs/architecture.md +77 -21
  48. package/docs/binding-review-placement-design.md +200 -0
  49. package/docs/capability-projection.md +1 -1
  50. package/docs/client-ui.md +95 -19
  51. package/docs/durability-design.md +28 -10
  52. package/docs/evaluation.md +78 -6
  53. package/docs/installation.md +41 -6
  54. package/docs/publishing.md +5 -3
  55. package/docs/runtime-reference.md +76 -25
  56. package/docs/semantic-validation.md +29 -0
  57. package/docs/stateful-binding-updates-proposal.md +759 -0
  58. package/docs/user-bindings.en.md +66 -0
  59. package/docs/user-bindings.md +66 -0
  60. package/docs/value-wire.md +3 -3
  61. package/docs/verification-optimization-work.md +41 -0
  62. package/docs/verification.md +71 -0
  63. package/index.js +369 -92
  64. package/internal/ast-traversal.js +5 -2
  65. package/internal/async-local-storage-intrinsics.js +38 -0
  66. package/internal/binding-declaration-contract.js +8 -0
  67. package/internal/binding-descriptors.js +1 -0
  68. package/internal/binding-pattern-traversal.js +25 -0
  69. package/internal/binding-pattern.js +26 -29
  70. package/internal/binding-source-analysis.js +708 -0
  71. package/internal/binding-update-policy.js +72 -0
  72. package/internal/bounded-worker-round.js +56 -0
  73. package/internal/callable-definition-environment.js +42 -0
  74. package/internal/callable-source-catalog.js +129 -0
  75. package/internal/callable-source-encoding.js +47 -0
  76. package/internal/callable-source-facts.js +459 -0
  77. package/internal/callable-source-format.js +2 -0
  78. package/internal/callable-source-lowering.js +123 -0
  79. package/internal/cell-analysis-contract.js +25 -0
  80. package/internal/cell-analysis.js +253 -290
  81. package/internal/cell-completion.js +15 -0
  82. package/internal/cell-error.js +7 -0
  83. package/internal/cell-parser.js +66 -0
  84. package/internal/cell-rewriter.js +3 -677
  85. package/internal/commonjs-export-evidence.js +63 -0
  86. package/internal/commonjs-source-evidence.js +72 -0
  87. package/internal/compiler-amaro.cjs +2 -0
  88. package/internal/compiler-compression.js +12 -0
  89. package/internal/compiler-data.js +58 -0
  90. package/internal/compiler-descriptors.js +54 -0
  91. package/internal/compiler-dynamic-cache.js +48 -0
  92. package/internal/compiler-entry.js +35 -0
  93. package/internal/compiler-generated-names.js +17 -0
  94. package/internal/compiler-intrinsics.js +50 -0
  95. package/internal/compiler-module-links.js +37 -0
  96. package/internal/compiler-operations.js +61 -0
  97. package/internal/compiler-platform-factory.js +84 -0
  98. package/internal/compiler-platform.js +136 -0
  99. package/internal/compiler-record-roles.js +53 -0
  100. package/internal/compiler-region-output.js +259 -0
  101. package/internal/compiler-resource-lowering.js +103 -0
  102. package/internal/compiler-scope-facts.js +115 -0
  103. package/internal/compiler-service.js +109 -0
  104. package/internal/compiler-source-cache.js +32 -0
  105. package/internal/compiler-source-pieces.js +93 -0
  106. package/internal/compiler-source-regions.js +132 -0
  107. package/internal/compiler-storage-source.js +54 -0
  108. package/internal/compiler-text.js +15 -0
  109. package/internal/compiler-typescript.cjs +2 -0
  110. package/internal/config-spec.js +83 -27
  111. package/internal/cordis-tools-owner.js +130 -21
  112. package/internal/diagnostic.js +27 -1
  113. package/internal/direct-surface-owner.js +76 -23
  114. package/internal/dynamic-binding-evidence.js +16 -0
  115. package/internal/dynamic-environment-compiler.js +779 -0
  116. package/internal/dynamic-environment-integration.js +91 -0
  117. package/internal/dynamic-environment-runtime.js +383 -0
  118. package/internal/dynamic-native-calls.js +153 -0
  119. package/internal/dynamic-native-runtime.js +262 -0
  120. package/internal/dynamic-scope-analysis.js +90 -0
  121. package/internal/edit-transport-owner.js +27 -2
  122. package/internal/execution-seam-compat.js +193 -0
  123. package/internal/failure-reporting.js +136 -28
  124. package/internal/host-rpc.js +66 -0
  125. package/internal/isolated-worker.js +555 -0
  126. package/internal/kernel-child.js +139 -0
  127. package/internal/kernel-worker.js +1179 -233
  128. package/internal/language-semantics.js +14 -0
  129. package/internal/legacy-binding-catalog.js +48 -0
  130. package/internal/legacy-cell-analysis.js +600 -0
  131. package/internal/legacy-cell-parser.js +50 -0
  132. package/internal/legacy-cell-rewriter.js +631 -0
  133. package/internal/legacy-repl-convenience.js +291 -0
  134. package/internal/managed-module-operations.js +170 -0
  135. package/internal/module-compilation.js +322 -0
  136. package/internal/module-runtime-platform.js +19 -0
  137. package/internal/module-transform-contract.js +42 -0
  138. package/internal/native-await-declarations.js +68 -0
  139. package/internal/native-root-compilation.js +54 -0
  140. package/internal/native-root-dynamic.js +67 -0
  141. package/internal/record-utils.js +24 -15
  142. package/internal/recovery-tips.js +27 -15
  143. package/internal/rejected-cell-editor.js +13 -8
  144. package/internal/repl-convenience.js +2 -289
  145. package/internal/repl-memory-projection.js +81 -12
  146. package/internal/repl-observation-interest.js +70 -0
  147. package/internal/repl-rewrite-contract.js +6 -0
  148. package/internal/repl-scope-normalizer.js +2091 -0
  149. package/internal/repl-value-observer.js +117 -0
  150. package/internal/rpc-contract.js +52 -0
  151. package/internal/runtime-bridge-owner.js +172 -28
  152. package/internal/runtime-config.js +48 -52
  153. package/internal/runtime-contexts.js +82 -10
  154. package/internal/runtime-intrinsics.js +101 -0
  155. package/internal/runtime-messages.js +111 -0
  156. package/internal/session-cell-executor.js +402 -87
  157. package/internal/session-journal-recovery.js +684 -0
  158. package/internal/session-journal-schema.js +123 -0
  159. package/internal/session-journal.js +199 -654
  160. package/internal/session-log-view.js +42 -9
  161. package/internal/session-runtime.js +257 -95
  162. package/internal/session-state.js +247 -71
  163. package/internal/source-position-map.js +230 -71
  164. package/internal/stateful-module-compiler.js +154 -0
  165. package/internal/stateful-module-runtime.js +303 -0
  166. package/internal/stateful-root-compiler.js +600 -0
  167. package/internal/stateful-root-runtime.js +340 -0
  168. package/internal/typert-codec-compat.js +28 -0
  169. package/internal/typescript-transform.js +31 -0
  170. package/internal/user-binding-authoring.js +70 -0
  171. package/internal/user-binding-console-worker.js +244 -0
  172. package/internal/user-binding-console.js +148 -0
  173. package/internal/user-binding-draft-projection.js +335 -0
  174. package/internal/user-binding-model-context.js +31 -0
  175. package/internal/user-binding-runner.js +56 -0
  176. package/internal/user-bindings-owner.js +1065 -0
  177. package/internal/user-bindings-store.js +293 -0
  178. package/internal/user-bindings.js +361 -0
  179. package/internal/value-wire-schema.js +28 -0
  180. package/internal/value-wire.js +130 -91
  181. package/internal/worker-client.js +57 -67
  182. package/internal/worker-cwd-virtualization.js +80 -53
  183. package/internal/worker-environment.js +65 -0
  184. package/internal/worker-output-relay.js +29 -0
  185. package/internal/worker-repl-realm.js +134 -0
  186. package/internal/worker-shutdown.js +14 -0
  187. package/package.json +76 -7
  188. package/src/client-activity.js +95 -53
  189. package/src/client-authoring-view.js +580 -0
  190. package/src/client-binding-review.js +230 -0
  191. package/src/client-bindings-data.js +29 -0
  192. package/src/client-catalog.js +127 -0
  193. package/src/client-code-editor.js +84 -0
  194. package/src/client-console.js +112 -0
  195. package/src/client-copy.js +370 -0
  196. package/src/client-feature-gates.js +62 -0
  197. package/src/client-host-compat.js +150 -0
  198. package/src/client-indicator-view.js +267 -0
  199. package/src/client-repl-view.js +292 -0
  200. package/src/client-rpc.js +20 -0
  201. package/src/client-settings-view.js +221 -0
  202. package/src/client-styles.js +106 -0
  203. package/src/client-tool-view.js +108 -0
  204. package/src/client-transport.js +159 -0
  205. package/src/client-workbench.js +521 -0
  206. package/src/client.js +233 -615
@@ -0,0 +1,2091 @@
1
+ import { commonJsCompilerImport, commonJsCompilerGlobals } from './compiler-module-links.js'
2
+ import { compilerStorageSource } from './compiler-storage-source.js'
3
+ import { compilerDescriptorSource } from './compiler-descriptors.js'
4
+ import { privateGeneratedRecords } from './compiler-record-roles.js'
5
+ import { lowerResourceOperations } from './compiler-resource-lowering.js'
6
+ import { callableDefinitionOwner, closeDefinitionExpression } from './callable-definition-environment.js'
7
+ /** Build logical binding identities from recovered syntax and Babel scope facts. */
8
+ import { parse } from '@babel/parser'
9
+ import traverseImport from '@babel/traverse'
10
+ import { SourceMap } from 'node:module'
11
+ import loadTypeScript from './compiler-typescript.cjs'
12
+ import { fileURLToPath } from 'node:url'
13
+ import { transformSync, transformFromAstSync, types as babelTypes } from '@babel/core'
14
+ import decoratorTransform from '@babel/plugin-proposal-decorators'
15
+ import typescriptTransform from '@babel/plugin-transform-typescript'
16
+ import resourceTransform from '@babel/plugin-transform-explicit-resource-management'
17
+ import generatorImport from '@babel/generator'
18
+ import { injectInitialization } from '@babel/helper-create-class-features-plugin'
19
+ import * as legacyDecoratorHelpers from 'tslib'
20
+ import { bindingNodes, createGeneratedNameAllocator } from './binding-pattern.js'
21
+ import { applySourceEdits, identitySourceMap, mappedSourceTransform, mapSourcePosition } from './source-position-map.js'
22
+ import { supportsNativeUsing, transformTypeScriptSource } from './typescript-transform.js'
23
+ import { createDynamicScopeAnalysis, varInitializerTarget } from './dynamic-scope-analysis.js'
24
+ import { visitSource } from './compiler-source-regions.js'
25
+ import { analyzeSourceDeclarations, resolveSourceBinding, COMMONJS_PARAMETERS } from './compiler-scope-facts.js'
26
+ import { callableMarkerPosition } from './callable-source-facts.js'
27
+ import { createSourcePieces } from './compiler-source-pieces.js'
28
+ import { indexSourceRegions, validateRegionSource, sourceFeatures } from './compiler-region-output.js'
29
+
30
+ export const CELL_PARSER_PLUGINS = ['typescript', 'importAttributes', 'decorators', 'decoratorAutoAccessors']
31
+
32
+ /** Babel parse errors the stateful cell compiler recovers from by design. */
33
+ export const RECOVERABLE_CELL_PARSE_ERRORS = new Set(['VarRedeclaration', 'DeclarationMissingInitializer',
34
+ 'DuplicateExport', 'DuplicateDefaultExport', 'UnexpectedUsingDeclaration'])
35
+
36
+ const PARSER_OPTIONS = {
37
+ sourceType: 'script',
38
+ allowAwaitOutsideFunction: true,
39
+ allowImportExportEverywhere: true,
40
+ allowReturnOutsideFunction: true,
41
+ allowUndeclaredExports: true,
42
+ plugins: CELL_PARSER_PLUGINS,
43
+ }
44
+
45
+ const parserOptionsForTarget = target => ({ ...PARSER_OPTIONS,
46
+ sourceType: target === 'module' || target === 'reflection-module' ? 'module' : target === 'commonjs' ? 'commonjs' : 'script',
47
+ ...(target === 'commonjs' ? { allowAwaitOutsideFunction: undefined, allowReturnOutsideFunction: undefined } : {}),
48
+ })
49
+
50
+ const LOOP_HEADS = new Set(['ForStatement', 'ForInStatement', 'ForOfStatement'])
51
+
52
+ function isFunctionNode(node) {
53
+ return node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression'
54
+ || node.type === 'ArrowFunctionExpression' || node.type === 'ObjectMethod'
55
+ || node.type === 'ClassMethod' || node.type === 'ClassPrivateMethod'
56
+ }
57
+
58
+ function eachNode(root, visit) {
59
+ babelTypes.traverseFast(root, visit)
60
+ }
61
+
62
+ function parseRecovered(code) {
63
+ return parse(code, { ...PARSER_OPTIONS, errorRecovery: true }).program
64
+ }
65
+
66
+ function singleStatementBodies(program) {
67
+ const bodies = new Map()
68
+ eachNode(program, (node) => {
69
+ if (node.type === 'IfStatement') {
70
+ if (node.consequent !== null) bodies.set(node.consequent, node)
71
+ if (node.alternate !== null) bodies.set(node.alternate, node)
72
+ return
73
+ }
74
+ if (node.type === 'WhileStatement' || node.type === 'DoWhileStatement'
75
+ || LOOP_HEADS.has(node.type) || node.type === 'WithStatement' || node.type === 'LabeledStatement') {
76
+ bodies.set(node.body, node)
77
+ }
78
+ })
79
+ return bodies
80
+ }
81
+
82
+ /**
83
+ * A function declaration written as the body of an `if`, loop, `with`, or `do`
84
+ * statement is the Annex B single-statement form, which the language defines as
85
+ * if it were written in a block. Writing that block keeps the declaration's own
86
+ * binding: without it, the parser's scope analysis reads the declaration as a
87
+ * var collision with an enclosing lexical and rejects a cell the language runs.
88
+ * A labelled function declaration hoists into the enclosing scope instead, so it
89
+ * is not this form and stays as written.
90
+ */
91
+ function annexBBlockEdits(program) {
92
+ const bodies = singleStatementBodies(program)
93
+ const edits = []
94
+ for (const [body, statement] of bodies) {
95
+ if (body.type !== 'FunctionDeclaration' || statement.type === 'LabeledStatement') continue
96
+ edits.push({ start: body.start, end: body.start, text: '{' })
97
+ edits.push({ start: body.end, end: body.end, text: '}' })
98
+ }
99
+ return edits
100
+ }
101
+
102
+ const traverseScopes = traverseImport.default ?? traverseImport
103
+ const generate = generatorImport.default ?? generatorImport
104
+
105
+ /** Owned entries obtain compiler operations from their prepared realm. Source
106
+ * bindings and mutable constructor properties never select helper authority. */
107
+ function intrinsicBootstrap(name, target, intrinsicContext) {
108
+ if (intrinsicContext) {
109
+ intrinsicContext.bindings.add(name)
110
+ return `const ${name}=(${intrinsicContext.expression ?? 'void 0'});\n`
111
+ }
112
+ if (target === 'module') return `import {moduleBindingIntrinsics as ${name}} from ${JSON.stringify(new URL('./stateful-module-runtime.js', import.meta.url).href)};\n`
113
+ if (target === 'commonjs') return `const ${name}=${commonJsCompilerImport(new URL('./compiler-intrinsics.js', import.meta.url))}.moduleCompilerIntrinsics;\n`
114
+ return `const ${name}=(()=>{const native=(function(){}).constructor("return {WeakMap,WeakSet,Reflect,Promise,Array,Function,SuppressedError:typeof SuppressedError==='function'?SuppressedError:void 0}")(),object=(${compilerDescriptorSource})(({}).constructor,native.Reflect).Object;let typeError,referenceError;try{null.x}catch(error){typeError=error.constructor}try{const value=value}catch(error){referenceError=error.constructor}return {Object:object,WeakMap:native.WeakMap,WeakSet:native.WeakSet,Reflect:{apply:(function(){}).call.bind((function(){}).apply),get decorate(){return native.Reflect.decorate}},TypeError:typeError,ReferenceError:referenceError,Error:object.getPrototypeOf(typeError),Symbol:object.getOwnPropertySymbols([].constructor.prototype)[0].constructor,String:''.constructor,Number:(0).constructor,Promise:{resolve:native.Promise.resolve.bind(native.Promise),reject:native.Promise.reject.bind(native.Promise)},SuppressedError:native.SuppressedError,...(${compilerStorageSource})(object,native.WeakMap,native.WeakSet,object.getOwnPropertySymbols([].constructor.prototype)[0].constructor,native.Promise,native.Reflect,native.Array,native.Function.prototype)}})();\n`
115
+ }
116
+
117
+ /** Resolve only compiler-recorded bootstrap declarations after the root frame
118
+ * has an execution owner. User declarations never select this private input. */
119
+ export function bindCompilerIntrinsics(result, intrinsicContext) {
120
+ if (intrinsicContext.bindings.size === 0) return result
121
+ const edits = []
122
+ eachNode(parseRecovered(result.code), node => {
123
+ if (node.type !== 'VariableDeclarator' || !intrinsicContext.bindings.has(node.id.name)) return
124
+ edits.push({ start: node.init.start, end: node.init.end, text: `(${intrinsicContext.expression})` })
125
+ })
126
+ return { ...result, ...applySourceEdits(result.code, result.sourceMap, edits) }
127
+ }
128
+
129
+ function mappedTransform(code, sourceMap, transformed) {
130
+ return mappedSourceTransform(code, sourceMap, transformed)
131
+ }
132
+
133
+ const TRANSPARENT_NAME_PARENTS = new Set(['ParenthesizedExpression', 'TSAsExpression',
134
+ 'TSNonNullExpression', 'TSSatisfiesExpression', 'TSTypeAssertion'])
135
+
136
+ /** Native name inference sees through parentheses and type-only wrappers. */
137
+ function namedExpressionPath(path) {
138
+ while (path.parentPath && TRANSPARENT_NAME_PARENTS.has(path.parent.type)) path = path.parentPath
139
+ return path
140
+ }
141
+
142
+ /** Definition regions have no callable body scope. Give each class evaluation
143
+ * a lexical frame before Babel assigns decorator initialization helpers. */
144
+ function isolateDefinitionClassEvaluations(file, allocate, intrinsics) {
145
+ const visited = new WeakSet()
146
+ // A computed field key is coerced once per class evaluation while its field value is created per
147
+ // instance. The key therefore travels through a parameter of the containing class's own frame,
148
+ // instead of shared storage that a later evaluation or a detached callable would overwrite or miss.
149
+ const capturedKeys = new Map()
150
+ file.path.traverse({ ClassExpression: { exit(path) {
151
+ const node = path.node
152
+ if (visited.has(node)) return
153
+ visited.add(node)
154
+ const captured = capturedKeys.get(node) ?? []
155
+ const decorated = Boolean(node.decorators?.length
156
+ || node.body.body.some(member => member.decorators?.length || member.type === 'ClassAccessorProperty'))
157
+ if (!decorated && captured.length === 0) return
158
+ const expression = namedExpressionPath(path)
159
+ const parent = expression.parent
160
+ const field = ['ClassProperty', 'ClassPrivateProperty', 'ClassAccessorProperty'].includes(parent.type)
161
+ const propertyValue = expression.key === 'value' && (parent.type === 'ObjectProperty' || field)
162
+ if (node.id === null && propertyValue && parent.type === 'ObjectProperty' && parent.computed) {
163
+ // Coerce the original key before entering the definition frame. Its own
164
+ // data property carries the exact string/symbol without a shared cache.
165
+ const record = babelTypes.identifier(allocate('decorated_class_key_object'))
166
+ const key = babelTypes.identifier(allocate('decorated_class_key'))
167
+ const nativeObject = babelTypes.memberExpression(babelTypes.identifier(intrinsics), babelTypes.identifier('Object'))
168
+ const keys = method => babelTypes.memberExpression(babelTypes.callExpression(
169
+ babelTypes.memberExpression(nativeObject, babelTypes.identifier(method)), [record]), babelTypes.numericLiteral(0), true)
170
+ const declaration = babelTypes.variableDeclaration('const', [babelTypes.variableDeclarator(key,
171
+ babelTypes.objectExpression([babelTypes.objectProperty(babelTypes.identifier('value'),
172
+ babelTypes.logicalExpression('??', keys('getOwnPropertyNames'), keys('getOwnPropertySymbols')))]))])
173
+ const namedKey = babelTypes.memberExpression(babelTypes.cloneNode(key), babelTypes.identifier('value'))
174
+ const value = babelTypes.objectExpression([babelTypes.objectProperty(namedKey, expression.node, true)])
175
+ expression.parentPath.replaceWith(babelTypes.spreadElement(closeDefinitionExpression([declaration], value, [record, ...captured], [
176
+ babelTypes.objectExpression([babelTypes.objectProperty(parent.key, babelTypes.numericLiteral(0), true)]),
177
+ ])))
178
+ return
179
+ }
180
+ // Definition regions have no enclosing callable scope to host the frame, so the owner gate
181
+ // selects them. An anonymous decorated class needs that frame for its inferred name and for a
182
+ // computed field value's per-evaluation key wherever the class expression appears.
183
+ if (!callableDefinitionOwner(path) && captured.length === 0
184
+ && !(node.id === null && decorated && (!propertyValue || field))) return
185
+ let name
186
+ if (node.id === null) {
187
+ name = babelTypes.stringLiteral('')
188
+ if (expression.key === 'right' && (parent.type === 'AssignmentPattern' || parent.type === 'AssignmentExpression')
189
+ && parent.left.type === 'Identifier') {
190
+ name = babelTypes.stringLiteral(parent.left.name)
191
+ } else if (expression.key === 'init' && parent.type === 'VariableDeclarator' && parent.id.type === 'Identifier') {
192
+ name = babelTypes.stringLiteral(parent.id.name)
193
+ } else if (propertyValue) {
194
+ if (!parent.computed) {
195
+ const key = parent.key.type === 'PrivateName' ? '#' + parent.key.id.name : parent.key.name ?? String(parent.key.value)
196
+ if (parent.type !== 'ObjectProperty' || key !== '__proto__') name = babelTypes.stringLiteral(key)
197
+ } else {
198
+ const key = babelTypes.identifier(allocate('decorated_class_key'))
199
+ const object = babelTypes.identifier(allocate('decorated_class_key_object'))
200
+ const nativeObject = babelTypes.memberExpression(babelTypes.identifier(intrinsics), babelTypes.identifier('Object'))
201
+ const keys = method => babelTypes.memberExpression(babelTypes.callExpression(
202
+ babelTypes.memberExpression(nativeObject, babelTypes.identifier(method)), [object]), babelTypes.numericLiteral(0), true)
203
+ const convert = babelTypes.arrowFunctionExpression([object], babelTypes.logicalExpression('??', keys('getOwnPropertyNames'), keys('getOwnPropertySymbols')))
204
+ parent.key = babelTypes.assignmentExpression('=', key, babelTypes.callExpression(convert,
205
+ [babelTypes.objectExpression([babelTypes.objectProperty(parent.key, babelTypes.numericLiteral(0), true)])]))
206
+ const containing = expression.parentPath.findParent(path => path.isClass()).node
207
+ capturedKeys.set(containing, [...(capturedKeys.get(containing) ?? []), babelTypes.cloneNode(key)])
208
+ name = babelTypes.cloneNode(key)
209
+ }
210
+ }
211
+ }
212
+ const parameter = name !== undefined && !babelTypes.isStringLiteral(name)
213
+ ? babelTypes.identifier(allocate('decorated_class_name')) : undefined
214
+ const key = parameter === undefined ? name : babelTypes.memberExpression(parameter, babelTypes.identifier('value'))
215
+ const value = name === undefined ? node : babelTypes.memberExpression(babelTypes.objectExpression([
216
+ babelTypes.objectProperty(babelTypes.cloneNode(key), node, true),
217
+ ]), babelTypes.cloneNode(key), true)
218
+ path.replaceWith(closeDefinitionExpression([], value,
219
+ [...(parameter === undefined ? [] : [parameter]), ...captured], parameter === undefined ? [] : [
220
+ babelTypes.objectExpression([babelTypes.objectProperty(babelTypes.identifier('value'), name)]),
221
+ ]))
222
+ } } })
223
+ }
224
+
225
+ /** Give potentially colliding public methods distinct physical keys. Babel then
226
+ * decorates every original descriptor, and the first class decorator publishes
227
+ * their final descriptors in source order before user class decorators run. */
228
+ function computedDecoratorMembers(helper, allocate, intrinsics, lazy = false) {
229
+ const access = name => babelTypes.memberExpression(lazy
230
+ ? babelTypes.callExpression(babelTypes.identifier(helper), []) : babelTypes.identifier(helper), babelTypes.identifier(name))
231
+ const wrap = expression => {
232
+ if (expression.type !== 'MemberExpression') return babelTypes.callExpression(access('wrap'), [expression])
233
+ const receiver = babelTypes.identifier(allocate('computed_decorator_receiver'))
234
+ const key = babelTypes.identifier(allocate('computed_decorator_key'))
235
+ return babelTypes.callExpression(babelTypes.arrowFunctionExpression([receiver, key],
236
+ babelTypes.callExpression(access('wrap'), [babelTypes.memberExpression(receiver, key, true), receiver])),
237
+ [expression.object, expression.computed ? expression.property : babelTypes.stringLiteral(expression.property.name)])
238
+ }
239
+ return () => ({ pre(file) {
240
+ isolateDefinitionClassEvaluations(file, allocate, intrinsics)
241
+ file.path.traverse({ ObjectProperty(path) {
242
+ const {node}=path
243
+ let value=node.value
244
+ while((value.type.startsWith('TS')||value.type==='ParenthesizedExpression')&&value.expression) value=value.expression
245
+ if(node.computed||value.type!=='ClassExpression'||value.id!==null
246
+ ||!value.decorators?.length&&!value.body.body.some(member=>member.decorators?.length)) return
247
+ const name=node.key.name??String(node.key.value)
248
+ if(name==='__proto__') return
249
+ node.key=babelTypes.stringLiteral(name)
250
+ node.computed=true
251
+ } })
252
+ file.scope.crawl()
253
+ }, visitor: { Class(path) {
254
+ const members = path.node.body.body.filter(member => member.type === 'ClassMethod' && member.kind !== 'constructor')
255
+ if (members.length < 2 || !members.some(member => member.computed)
256
+ || !members.some(member => member.decorators?.length)) return
257
+ for (const member of members) {
258
+ const key = member.computed ? member.key : babelTypes.stringLiteral(member.key.name ?? String(member.key.value))
259
+ member.key = babelTypes.callExpression(access('key'), [key,
260
+ babelTypes.stringLiteral(member.kind), babelTypes.booleanLiteral(member.static)])
261
+ member.computed = true
262
+ member.decorators = [...(member.decorators ?? []).map(decorator => babelTypes.decorator(wrap(decorator.expression))),
263
+ babelTypes.decorator(access('prepare'))]
264
+ }
265
+ path.node.decorators = [...path.node.decorators ?? [], babelTypes.decorator(access('publish'))]
266
+ } } })
267
+ }
268
+
269
+ function computedDecoratorBootstrap(helper, intrinsics, storage) {
270
+ return `${storage ? `var ${storage};function ${helper}(){return ${storage}??=` : `const ${helper}=`}(()=>{const O=${intrinsics}.Object,records=${intrinsics}.weakMapStore();const display=name=>typeof name==="symbol"?(${intrinsics}.symbolDescription(name)===void 0?"":"["+${intrinsics}.symbolDescription(name)+"]"):name;return {
271
+ key(value,kind,isStatic){const object={[value]:0},name=O.getOwnPropertyNames(object)[0]??O.getOwnPropertySymbols(object)[0];if(isStatic&&name==="prototype")throw new ${intrinsics}.TypeError("Classes may not have a static property named prototype");const symbol=${intrinsics}.Symbol();records.set(symbol,{name,kind});return symbol},
272
+ prepare(value,context){const record=records.get(context.name);O.defineProperty(value,"name",{value:(record.kind==="get"?"get ":record.kind==="set"?"set ":"")+display(record.name),configurable:true})},
273
+ wrap(decorator,receiver){return function(value,context){const name=records.get(context.name).name;context.name=name;context.access={has:object=>name in object,...(context.kind==="setter"?{}:{get:object=>object[name]}),...(context.kind==="method"||context.kind==="getter"?{}:{set:(object,value)=>{object[name]=value}})};return ${intrinsics}.Reflect.apply(decorator,receiver,[value,context])}},
274
+ publish(C){for(const target of ${intrinsics}.array([C,C.prototype]))for(const symbol of ${intrinsics}.array(O.getOwnPropertySymbols(target))){const record=records.get(symbol);if(!record)continue;const descriptor=O.getOwnPropertyDescriptor(target,symbol);if(record.kind==="get"||record.kind==="set"){const previous=O.getOwnPropertyDescriptor(target,record.name);const other=record.kind==="get"?"set":"get";descriptor[other]=previous?.[other]}O.defineProperty(target,record.name,descriptor);delete target[symbol];records.delete(symbol)}return C}
275
+ }})();${storage ? '}' : ''}\n`
276
+ }
277
+
278
+ /** Lowerers supply helper and source provenance; this pass captures generated
279
+ * operations. Source nodes retain their locations and never enter this visitor's
280
+ * adaptation, even inside generated calls. Both lowerers consume one contract. */
281
+ function generatedHelperOperations(intrinsics, intrinsicNames, { arrays = true, records } = {}) {
282
+ const operation = name => babelTypes.memberExpression(babelTypes.identifier(intrinsics), babelTypes.identifier(name))
283
+ const functionOperations = { call: 'functionCall', apply: 'functionApply', bind: 'functionBind' }
284
+ const invocationTarget = node => babelTypes.isMemberExpression(node) && !node.computed && !node.loc
285
+ && Object.hasOwn(functionOperations, node.property.name) ? operation(functionOperations[node.property.name]) : node
286
+ return {
287
+ ObjectExpression: { exit(path) {
288
+ if (!records?.has(path.node)) return
289
+ path.replaceWith(babelTypes.callExpression(operation('record'), [path.node]))
290
+ path.skip()
291
+ } },
292
+ ArrayExpression: { exit(path) {
293
+ if (path.node.loc || !arrays) return
294
+ path.replaceWith(babelTypes.callExpression(operation('array'), [path.node]))
295
+ path.skip()
296
+ } },
297
+ CallExpression: { exit(path) {
298
+ const callee = path.node.callee
299
+ if (path.node.loc || !babelTypes.isMemberExpression(callee) || callee.computed) return
300
+ const kind = callee.property.name
301
+ if (Object.hasOwn(functionOperations, kind)) {
302
+ const [receiver, ...args] = kind === 'bind' ? [callee.object, ...path.node.arguments] : path.node.arguments
303
+ const target = kind === 'bind' ? operation('functionBind') : invocationTarget(callee.object)
304
+ const argumentList = kind === 'apply' ? args[0] : babelTypes.arrayExpression(args)
305
+ path.replaceWith(babelTypes.callExpression(babelTypes.memberExpression(operation('Reflect'),
306
+ babelTypes.identifier('apply')), [target, invocationTarget(receiver), argumentList]))
307
+ } else return
308
+ path.skip()
309
+ } },
310
+ Identifier(path) {
311
+ if (path.node.loc || !intrinsicNames.has(path.node.name) || !path.isReferencedIdentifier()) return
312
+ path.replaceWith(operation(path.node.name))
313
+ path.skip()
314
+ },
315
+ }
316
+ }
317
+
318
+ /** The maintained helper accepts a scalar-or-list member decorator slot.
319
+ * Normalize that union at emission: source values are elements, and only
320
+ * generated arrays (including memoized ones) carry the private list role. */
321
+ function normalizeGeneratedDecoratorLists(file) {
322
+ const helper = file.declarations.applyDecs2311
323
+ if (helper === undefined) return
324
+ const isList = (path, seen = new Set()) => {
325
+ if (!path.node || path.node.loc || seen.has(path.node)) return false
326
+ if (path.isArrayExpression()) return true
327
+ if (!path.isIdentifier()) return false
328
+ seen.add(path.node)
329
+ const binding = path.scope.getBinding(path.node.name)
330
+ if (binding === undefined) return false
331
+ const values = []
332
+ if (binding.path.isVariableDeclarator() && binding.path.node.init) values.push(binding.path.get('init'))
333
+ for (const write of binding.constantViolations) if (write.isAssignmentExpression()) values.push(write.get('right'))
334
+ return values.length > 0 && values.every(value => isList(value, seen))
335
+ }
336
+ file.path.traverse({ CallExpression(path) {
337
+ if (path.node.loc || !babelTypes.isIdentifier(path.node.callee, helper)) return
338
+ // applyDecs2311: [class, class decorators, member descriptions, ...].
339
+ for (const info of path.get('arguments')[2].get('elements')) {
340
+ const list = info.get('elements')[0]
341
+ if (!isList(list)) list.replaceWith(babelTypes.arrayExpression([list.node]))
342
+ }
343
+ } })
344
+ }
345
+
346
+ /** Babel owns decorator application and initialization. Only compiler-created
347
+ * identifiers are redirected to captured intrinsics; user expressions retain
348
+ * their own lexical resolution. Native fields/private methods need no lowering
349
+ * on the supported Node runtime. */
350
+ export function lowerStatefulDecorators(result, target, intrinsicContext) {
351
+ if (result.sourceRegions?.decorated === false && !result.deferredHelpers?.size) return result
352
+ if (result.deferredHelpers?.size) {
353
+ const edits = []
354
+ eachNode(parseRecovered(result.code), node => {
355
+ if (node.type !== 'VariableDeclaration' || node.declarations.length !== 1) return
356
+ const text = result.deferredHelpers.get(node.declarations[0].id.name)
357
+ if (text) edits.push({ start: node.start, end: node.end, text })
358
+ })
359
+ result = { ...result, ...applySourceEdits(result.code, result.sourceMap, edits) }
360
+ }
361
+ const tree = parse(result.code, { ...parserOptionsForTarget(target), errorRecovery: true })
362
+ let decorated = false
363
+ eachNode(tree, node => { if (node.decorators?.length || node.type === 'ClassAccessorProperty') decorated = true })
364
+ if (!decorated) return result
365
+ const allocate = createGeneratedNameAllocator(tree)
366
+ const intrinsics = allocate('decorator_intrinsics')
367
+ const computedMembers = allocate('computed_members')
368
+ const computedStorage = target === 'module' ? allocate('computed_records') : undefined
369
+ const internalBindings = new Set(result.internalBindings)
370
+ internalBindings.add(intrinsics)
371
+ const intrinsicNames = new Set(['Object', 'Reflect', 'TypeError', 'ReferenceError', 'Error', 'Symbol', 'String', 'Number'])
372
+ const frameDeclaration = statement => statement.type === 'VariableDeclaration'
373
+ && statement.declarations.some(binding => binding.id.name === result.rootFrameBinding)
374
+ const cellFrame = program => program.body.find(statement => statement.type === 'BlockStatement'
375
+ && statement.body.some(frameDeclaration))
376
+ // The feature scan owns this tree through lowering. Transfer it to Babel;
377
+ // recovered syntax retains Babel's original parsing and diagnostic path.
378
+ const transform = tree.errors.length === 0
379
+ ? options => transformFromAstSync(tree, result.code, { ...options, cloneInputAst: false })
380
+ : options => transformSync(result.code, options)
381
+ const transformed = transform({
382
+ filename: 'ptc-cell.ts', babelrc: false, configFile: false, browserslistConfigFile: false, sourceMaps: true,
383
+ parserOpts: parserOptionsForTarget(target),
384
+ plugins: [computedDecoratorMembers(computedMembers, allocate, intrinsics, target === 'module'),
385
+ [typescriptTransform, { allowDeclareFields: true, onlyRemoveTypeImports: true }],
386
+ [decoratorTransform, { version: '2023-11' }],
387
+ () => ({ post(file) {
388
+ normalizeGeneratedDecoratorLists(file)
389
+ file.path.traverse(generatedHelperOperations(intrinsics, intrinsicNames, {
390
+ arrays: !!intrinsicContext || target === 'module' || target === 'commonjs',
391
+ records: privateGeneratedRecords(file),
392
+ }))
393
+ for (const binding of Object.values(file.scope.bindings)) {
394
+ if (!binding.identifier.loc) internalBindings.add(binding.identifier.name)
395
+ }
396
+ if (result.rootFrameBinding !== undefined) {
397
+ const frame = cellFrame(file.ast.program)
398
+ const helpers = file.ast.program.body.filter(statement => statement !== frame && statement.type !== 'EmptyStatement')
399
+ file.ast.program.body = file.ast.program.body.filter(statement => statement === frame || statement.type === 'EmptyStatement')
400
+ frame.body.splice(frame.body.findIndex(frameDeclaration) + 1, 0, ...helpers.map(statement => {
401
+ if (!babelTypes.isFunctionDeclaration(statement)) return statement
402
+ // Native REPL block functions produce a value and may escape via
403
+ // Annex B. Helpers initialize before any user code in this frame.
404
+ const value = babelTypes.toExpression(statement)
405
+ return babelTypes.variableDeclaration('const', [babelTypes.variableDeclarator(babelTypes.cloneNode(value.id), value)])
406
+ }))
407
+ }
408
+ } })],
409
+ })
410
+ const applied = mappedTransform(result.code, result.sourceMap, transformed)
411
+ const parsed = parse(applied.code, parserOptionsForTarget(target))
412
+ const offset = result.rootFrameBinding === undefined ? parsed.program.directives.at(-1)?.end ?? 0
413
+ : cellFrame(parsed.program).body.find(frameDeclaration).end
414
+ const hasComputedMembers = transformed.code.includes(computedMembers)
415
+ if (hasComputedMembers) internalBindings.add(computedMembers)
416
+ if (hasComputedMembers && computedStorage) internalBindings.add(computedStorage)
417
+ const output = applySourceEdits(applied.code, applied.sourceMap, [
418
+ { start: offset, end: offset, text: '\n' + intrinsicBootstrap(intrinsics, target, intrinsicContext)
419
+ + (hasComputedMembers ? computedDecoratorBootstrap(computedMembers, intrinsics, computedStorage) : '') },
420
+ ])
421
+ return { ...result, ...output, internalBindings,
422
+ ...(result.sourceRegions === undefined ? {} : { sourceRegions: indexSourceRegions(output.code, parserOptionsForTarget(target)) }) }
423
+ }
424
+
425
+ /** Erase type-only declarations and lower runtime TypeScript values before
426
+ * logical ownership and module export/link plans consume the source. */
427
+ export function normalizeTypeScriptValues(code, sourceMap, target) {
428
+ const tree=parse(code,{...parserOptionsForTarget(target),errorRecovery:true})
429
+ let parameterProperties = false
430
+ let tokens
431
+ const declarationTokens = (node, owner = node) => {
432
+ tokens ??= new Map()
433
+ let result = tokens.get(node)
434
+ if (result === undefined) {
435
+ result = parse(code.slice(owner.start, owner.end), { ...parserOptionsForTarget(target), errorRecovery: true, tokens: true }).tokens
436
+ .map(token => ({ ...token, start: token.start + owner.start, end: token.end + owner.start }))
437
+ tokens.set(node, result)
438
+ }
439
+ return result
440
+ }
441
+ const edits=[]
442
+ visitSource(tree,{
443
+ TSParameterProperty() { parameterProperties = true },
444
+ Decorator(path) {
445
+ const expression=path.node.expression
446
+ if(expression.extra?.parenthesized) return
447
+ edits.push({start:expression.start,end:expression.start,text:'('},
448
+ {start:expression.end,end:expression.end,text:')'})
449
+ },
450
+ 'ExportNamedDeclaration|ExportDefaultDeclaration|ExportAllDeclaration'(path) {
451
+ if(path.node.exportKind==='type') {
452
+ edits.push({start:path.node.start,end:path.node.end,text:''})
453
+ path.skip()
454
+ return
455
+ }
456
+ const declaration=path.node.declaration
457
+ if(declaration?.type!=='ClassDeclaration'||declaration.declare===true
458
+ ||declaration.decorators?.[0]?.start!==path.node.start) return
459
+ const afterDecorators=declaration.decorators.at(-1).end
460
+ const modifiers=declarationTokens(path.node).filter(token=>token.start>=afterDecorators&&token.end<=declaration.body.start
461
+ &&(token.type.label==='export'||token.type.label==='default'))
462
+ let prefix=''
463
+ const mappings=[]
464
+ for(const token of modifiers) {
465
+ const text=code.slice(token.start,token.end)
466
+ mappings.push({generatedStart:prefix.length,generatedEnd:prefix.length+text.length,
467
+ originalStart:token.start,originalEnd:token.end})
468
+ prefix+=text+' '
469
+ edits.push({start:token.start,end:token.end,text:''})
470
+ }
471
+ edits.push({start:path.node.start,end:path.node.start,text:prefix,mappings})
472
+ },
473
+ 'TSTypeAliasDeclaration|TSInterfaceDeclaration|TSDeclareFunction'(path) {
474
+ const owner=path.parentPath.isExportNamedDeclaration()||path.parentPath.isExportDefaultDeclaration()?path.parent:path.node
475
+ edits.push({start:owner.start,end:owner.end,text:''})
476
+ path.skip()
477
+ },
478
+ 'TSDeclareMethod|ClassProperty|ClassPrivateProperty|ClassAccessorProperty'(path) {
479
+ if(path.node.type!=='TSDeclareMethod'&&path.node.abstract!==true&&path.node.declare!==true) return
480
+ edits.push({start:path.node.start,end:path.node.end,text:''})
481
+ path.skip()
482
+ },
483
+ ImportDeclaration(path) {
484
+ if(path.node.importKind==='type') {
485
+ edits.push({start:path.node.start,end:path.node.end,text:''})
486
+ return
487
+ }
488
+ const specifiers=path.node.specifiers.filter(specifier=>specifier.type==='ImportSpecifier')
489
+ if(!specifiers.some(specifier=>specifier.importKind==='type')) return
490
+ const kept=specifiers.filter(specifier=>specifier.importKind!=='type')
491
+ if(kept.length===0&&specifiers.length===path.node.specifiers.length) {
492
+ edits.push({start:path.node.start,end:path.node.end,text:''})
493
+ return
494
+ }
495
+ edits.push({start:specifiers[0].start,end:specifiers.at(-1).end,
496
+ text:kept.map(specifier=>code.slice(specifier.start,specifier.end)).join(',')})
497
+ },
498
+ 'VariableDeclaration|ClassDeclaration'(path) {
499
+ if(path.node.type==='ClassDeclaration'&&path.node.abstract===true&&path.node.declare!==true) {
500
+ const start=path.node.decorators?.at(-1)?.end??path.node.start
501
+ const owner=path.parentPath.isExportDefaultDeclaration()?path.parent:path.node
502
+ const modifier=declarationTokens(path.node,owner).find(token=>token.start>=start&&token.end<=path.node.body.start
503
+ &&token.type.label==='name'&&token.value==='abstract')
504
+ edits.push({start:modifier.start,end:modifier.end,text:''})
505
+ }
506
+ if(path.node.declare!==true) return
507
+ const owner=path.parentPath.isExportNamedDeclaration()||path.parentPath.isExportDefaultDeclaration()?path.parent:path.node
508
+ edits.push({start:owner.start,end:owner.end,text:''})
509
+ path.skip()
510
+ },
511
+ 'TSEnumDeclaration|TSModuleDeclaration'(path) {
512
+ const owner=path.parentPath.isExportNamedDeclaration()?path.parent:path.node
513
+ let source=code.slice(path.node.start,path.node.end)
514
+ const enumEdits=[]
515
+ babelTypes.traverseFast(path.node,node=>{
516
+ if(node.type!=='TSEnumDeclaration'||node.const!==true) return
517
+ const modifier=declarationTokens(node).find(token=>token.type.label==='const')
518
+ enumEdits.push({start:modifier.start-path.node.start,end:modifier.end-path.node.start,
519
+ text:' '.repeat(modifier.end-modifier.start)})
520
+ })
521
+ if(enumEdits.length>0) source=applySourceEdits(source,identitySourceMap(source.length),enumEdits).code
522
+ const transformed=transformTypeScriptSource(source,{module:target!=='commonjs',sourceMap:true,
523
+ transform:{tsEnumIsMutable:true,noEmptyExport:true}})
524
+ const nativeMap=new SourceMap(JSON.parse(transformed.map))
525
+ const starts=[0]
526
+ for(let index=0;index<source.length;index++) if(source[index]==='\n') starts.push(index+1)
527
+ const mappings=[]
528
+ let line=1,column=1
529
+ for(let index=0;index<transformed.code.length;index++) {
530
+ const origin=nativeMap.findOrigin(line,column)
531
+ const start=Math.min(source.length,Math.max(0,(starts[origin.lineNumber-1]??0)+(origin.columnNumber??1)-1))
532
+ mappings.push({generatedStart:index,generatedEnd:index+1,originalStart:path.node.start+start,
533
+ originalEnd:Math.min(owner.end,path.node.start+start+1)})
534
+ if(transformed.code[index]==='\n'){line++;column=1}else column++
535
+ }
536
+ const exported=owner!==path.node&&transformed.code.trim()!==''?`\nexport {${path.node.id.name}};`:''
537
+ edits.push({start:owner.start,end:owner.end,text:transformed.code+exported,mappings})
538
+ path.skip()
539
+ },
540
+ })
541
+ const result = applySourceEdits(code,sourceMap,edits)
542
+ return parameterProperties ? lowerParameterProperties(result) : result
543
+ }
544
+
545
+ /** Shared language lowering without logical binding or dynamic-environment rewriting. */
546
+ export function lowerNativeLanguageSource(code, { sourceType = 'script', nativeUsing } = {}) {
547
+ // Module syntax is a parsing context here, not a module bootstrap dependency.
548
+ const target = sourceType === 'module' ? 'reflection-module' : undefined
549
+ const options = parserOptionsForTarget(target)
550
+ const typed = normalizeTypeScriptValues(code, identitySourceMap(code.length), target)
551
+ const parameters = lowerLegacyParameterDecorators(typed, target)
552
+ const tree = parse(parameters.code, { ...options, errorRecovery: true })
553
+ const result = tree.errors.length > 0 ? normalizeStatefulScopes(code, undefined, { target, nativeUsing })
554
+ : lowerStatefulResources(lowerStatefulDecorators(parameters, target), { target, nativeUsing })
555
+ try {
556
+ parse(result.code, { ...options, plugins: [], errorRecovery: true })
557
+ return result.code
558
+ } catch {
559
+ return transformSync(result.code, { filename: 'ptc-source.ts', babelrc: false, configFile: false, browserslistConfigFile: false,
560
+ parserOpts: { ...options, errorRecovery: true },
561
+ plugins: [[typescriptTransform, { allowDeclareFields: true, onlyRemoveTypeImports: true }]],
562
+ }).code
563
+ }
564
+ }
565
+
566
+ /** Parameter properties must become ordinary parameters and writes before scope
567
+ * ownership is assigned. Babel owns insertion after every reachable super(). */
568
+ function lowerParameterProperties(result) {
569
+ let needed = false
570
+ eachNode(parseRecovered(result.code), node => { if (node.type === 'TSParameterProperty') needed = true })
571
+ if (!needed) return result
572
+ const parameterProperties = new Map()
573
+ const facts = analyzeLogicalScopes(result.code, { parameterProperties, mutablePaths: true })
574
+ for (const [node, name] of facts.names) node.name = name
575
+ for (const [node, path] of facts.paths) {
576
+ if (node.type !== 'ClassMethod' || node.kind !== 'constructor') continue
577
+ const properties = parameterProperties.get(node) ?? []
578
+ if (!properties.length) continue
579
+ if (path.parent.body.findLast(member => member.type === 'ClassMethod' && member.kind === 'constructor') !== node) continue
580
+ const names = properties.map(property => bindingNodes(property.parameter)[0].name)
581
+ const skeleton = `class C{constructor(${names.map(name => `public ${name}:unknown`).join(',')}){}}`
582
+ const lowered = transformTypeScriptSource(skeleton, { transform: { noEmptyExport: true } }).code
583
+ const members = parse(lowered, { ...PARSER_OPTIONS, errorRecovery: true }).program.body[0].body.body
584
+ const assignments = members.find(member => member.type === 'ClassMethod').body.body
585
+ path.parent.body.unshift(...members.filter(member => member.type === 'ClassProperty'))
586
+ injectInitialization(path.parentPath.parentPath, path, assignments)
587
+ }
588
+ return mappedTransform(result.code, result.sourceMap, generate(facts.tree,
589
+ { sourceMaps: true, sourceFileName: 'ptc-cell.ts' }, result.code))
590
+ }
591
+
592
+ /** Parameter decorators select TypeScript's legacy decorator convention. The
593
+ * maintained compiler lowers their class/parameter phases before logical scopes;
594
+ * tslib helpers are private compiler bindings with captured language intrinsics. */
595
+ function lowerLegacyParameterDecorators(result, target, intrinsicContext) {
596
+ let needed = false
597
+ eachNode(parseRecovered(result.code), node => {
598
+ if (isFunctionNode(node) && node.params.some(parameter => parameter.decorators?.length)) needed = true
599
+ })
600
+ if (!needed) return result
601
+ const ts = loadTypeScript()
602
+ const expressionIntrinsics = createGeneratedNameAllocator(parseRecovered(result.code))('legacy_intrinsics')
603
+ const expressionBindings = new Set()
604
+ const internalPrivateNames = new Set()
605
+ const expressionClasses = new Map()
606
+ while (true) {
607
+ const facts = analyzeLogicalScopes(result.code, { mutablePaths: true })
608
+ const expressionTree = facts.tree
609
+ const names = createGeneratedNameAllocator(expressionTree, expressionClasses.keys())
610
+ let selected = [...facts.paths.values()].filter(path => path.isClassExpression()
611
+ && path.node.body.body.some(member => member.params?.some(parameter => parameter.decorators?.length)))
612
+ .sort((left, right) => left.node.end - left.node.start - (right.node.end - right.node.start))[0]
613
+ if (!selected) break
614
+ // A computed field initializer runs after its key was evaluated. Its key
615
+ // cache belongs to this class definition, including repeated loop entries.
616
+ while (['ClassProperty', 'ClassAccessorProperty'].includes(selected.parent.type)
617
+ && selected.parent.computed && !['StringLiteral', 'NumericLiteral'].includes(selected.parent.key.type)) {
618
+ const owner = selected.findParent(path => path.isClass())
619
+ if (expressionClasses.has(facts.names.get(owner.node.id))) break
620
+ selected = owner
621
+ }
622
+ const node = selected.node
623
+ const declarationId = selected.isClassDeclaration() ? node.id : undefined
624
+ const name = names('legacy_class_expression')
625
+ const parent = selected.parent
626
+ let inferredName = ''
627
+ let inferredKey
628
+ if ((parent.type === 'VariableDeclarator' && parent.init === node && parent.id.type === 'Identifier')
629
+ || (parent.type === 'AssignmentPattern' || parent.type === 'AssignmentExpression') && parent.right === node && parent.left.type === 'Identifier') {
630
+ const identifier = parent.id ?? parent.left
631
+ inferredName = facts.names.get(identifier) ?? identifier.name
632
+ } else if (['ObjectProperty', 'ClassProperty', 'ClassAccessorProperty'].includes(parent.type) && parent.value === node
633
+ && (!parent.computed || ['StringLiteral', 'NumericLiteral'].includes(parent.key.type))) {
634
+ inferredName = parent.key.name ?? String(parent.key.value)
635
+ if (parent.type === 'ObjectProperty' && !parent.computed && inferredName === '__proto__') inferredName = ''
636
+ } else if (['ObjectProperty', 'ClassProperty', 'ClassAccessorProperty'].includes(parent.type)
637
+ && parent.value === node && parent.computed) {
638
+ inferredKey = names('legacy_class_key')
639
+ expressionBindings.add(inferredKey)
640
+ const object = names('legacy_key_object')
641
+ expressionBindings.add(object)
642
+ selected.scope.push({ id: babelTypes.identifier(inferredKey), kind: 'let', unique: true })
643
+ const coercion = parse(`(${inferredKey}=((${object})=>${expressionIntrinsics}.Object.getOwnPropertyNames(${object})[0]??${expressionIntrinsics}.Object.getOwnPropertySymbols(${object})[0])({[0]:0}))`, PARSER_OPTIONS).program.body[0].expression
644
+ coercion.right.arguments[0].properties[0].key = parent.key
645
+ parent.key = coercion
646
+ if (parent.type !== 'ObjectProperty') {
647
+ const owner = selected.findParent(path => path.isClass()).node
648
+ const ownerName = facts.names.get(owner.id)
649
+ const metadata = expressionClasses.get(ownerName)
650
+ if (metadata.suspending) {
651
+ const storage = names('legacy_field_key')
652
+ const field = babelTypes.classPrivateProperty(babelTypes.privateName(babelTypes.identifier(storage)),
653
+ babelTypes.identifier(inferredKey))
654
+ field.static = true
655
+ owner.body.body.unshift(field)
656
+ internalPrivateNames.add(storage)
657
+ metadata.retainSelf = metadata.originalName === undefined
658
+ inferredKey = `${metadata.originalName ?? ownerName}.#${storage}`
659
+ }
660
+ }
661
+ } else if (parent.type === 'ExportDefaultDeclaration') inferredName = 'default'
662
+ expressionClasses.set(name, { originalName: facts.names.get(node.id), inferredName, inferredKey })
663
+ node.type = 'ClassDeclaration'
664
+ node.id = babelTypes.identifier(name)
665
+ const invocation = babelTypes.callExpression(babelTypes.arrowFunctionExpression([], babelTypes.blockStatement([
666
+ node, babelTypes.returnStatement(babelTypes.identifier(name)),
667
+ ])), [])
668
+ if (declarationId) {
669
+ const publicName = babelTypes.cloneNode(declarationId)
670
+ facts.names.set(publicName, facts.names.get(declarationId))
671
+ selected.replaceWith(babelTypes.variableDeclaration('let', [babelTypes.variableDeclarator(publicName, invocation)]))
672
+ selected = selected.get('declarations.0.init')
673
+ } else selected.replaceWith(invocation)
674
+ const wrapper = selected.get('callee')
675
+ const decorators = []
676
+ // Legacy decorators evaluate in the outer lexical environment. Include
677
+ // their expressions when classifying suspension, then restore their phase.
678
+ wrapper.get('body').traverse(traverseScopes.visitors.environmentVisitor({ Class(path) {
679
+ for (const owner of [path.node, ...path.node.body.body.flatMap(member => [member, ...member.params ?? []])]) {
680
+ if (!owner.decorators?.length) continue
681
+ const values = owner.decorators.map(decorator => {
682
+ const expression = babelTypes.cloneNode(decorator.expression)
683
+ const parsed = babelTypes.file(babelTypes.program([babelTypes.expressionStatement(expression)]))
684
+ traverseScopes(parsed, { noScope: true, Identifier(path) {
685
+ // The TypeScript parameter-decorator parser treats these tokens as
686
+ // identifiers; native lexical conversion requires their real nodes.
687
+ if (!path.isReferencedIdentifier() || !['this', 'super'].includes(path.node.name)) return
688
+ const replacement = path.node.name === 'this' ? babelTypes.thisExpression() : babelTypes.super()
689
+ replacement.loc = path.node.loc
690
+ path.replaceWith(replacement)
691
+ } })
692
+ return { decorator, statement: parsed.program.body[0] }
693
+ })
694
+ decorators.push({ owner, values })
695
+ owner.decorators = []
696
+ }
697
+ } }))
698
+ const probes = new Set(decorators.flatMap(({ values }) => values.map(({ statement }) => statement)))
699
+ wrapper.node.body.body.unshift(...probes)
700
+ let awaited = false, yielded = false
701
+ wrapper.get('body').traverse(traverseScopes.visitors.environmentVisitor({
702
+ ArrowFunctionExpression(path) { path.skip() },
703
+ AwaitExpression() { awaited = true },
704
+ YieldExpression() { yielded = true },
705
+ }))
706
+ if (yielded) {
707
+ wrapper.node.type = 'FunctionExpression'
708
+ wrapper.node.generator = true
709
+ wrapper.node.async = awaited
710
+ } else if (awaited) wrapper.node.async = true
711
+ expressionClasses.get(name).suspending = awaited || yielded
712
+ wrapper.node.body.body = wrapper.node.body.body.filter(statement => !probes.has(statement))
713
+ for (const { owner, values } of decorators) {
714
+ owner.decorators = values.map(({ decorator, statement }) => {
715
+ decorator.expression = statement.expression
716
+ return decorator
717
+ })
718
+ }
719
+ eachNode(expressionTree, current => {
720
+ if (current.type !== 'VariableDeclarator' || current.id.type !== 'Identifier' || current.id.loc) return
721
+ expressionBindings.add(current.id.name)
722
+ })
723
+ for (const [identifier, originalName] of facts.names) identifier.name = originalName
724
+ result = mappedTransform(result.code, result.sourceMap, generate(expressionTree,
725
+ { sourceMaps: true, sourceFileName: 'ptc-cell.ts' }, result.code))
726
+ }
727
+ const tree = parse(result.code, { ...PARSER_OPTIONS, errorRecovery: true })
728
+ const allocate = createGeneratedNameAllocator(tree)
729
+ const marker = allocate('legacy_module_marker')
730
+ const preserved = new Map()
731
+ const masks = []
732
+ const preserve = (node, accessor = false) => {
733
+ const name = allocate('standard_decorator')
734
+ preserved.set(name, { text: result.code.slice(node.start, node.end), accessor })
735
+ masks.push({ start: node.start, end: node.end, text: accessor ? `${name}(){}` : `/*${name}*/` })
736
+ }
737
+ traverseScopes(tree, { noScope: true, Class(path) {
738
+ if (path.node.body.body.some(member => member.params?.some(parameter => parameter.decorators?.length))) return
739
+ for (const decorator of path.node.decorators ?? []) preserve(decorator)
740
+ for (const member of path.node.body.body) {
741
+ if (member.type === 'ClassAccessorProperty') { preserve(member, true); continue }
742
+ for (const decorator of member.decorators ?? []) preserve(decorator)
743
+ }
744
+ } })
745
+ const masked = applySourceEdits(result.code, result.sourceMap, masks)
746
+ const transformed = ts.transpileModule(masked.code + `\nexport const ${marker}=0;`, {
747
+ fileName: 'ptc-cell.ts', compilerOptions: { target: ts.ScriptTarget.ESNext,
748
+ module: ts.ModuleKind.ESNext, experimentalDecorators: true, importHelpers: true,
749
+ sourceMap: true, verbatimModuleSyntax: true },
750
+ })
751
+ let applied = mappedTransform(masked.code, masked.sourceMap,
752
+ { code: transformed.outputText, map: transformed.sourceMapText })
753
+ const lowered = parse(applied.code, { ...PARSER_OPTIONS, errorRecovery: true })
754
+ const emittedMap = new SourceMap(JSON.parse(transformed.sourceMapText))
755
+ const intrinsics = expressionIntrinsics
756
+ const internalBindings = new Set([intrinsics, ...expressionClasses.keys(), ...expressionBindings])
757
+ const deferredHelpers = new Map([[intrinsics, intrinsicBootstrap(intrinsics, target, intrinsicContext)]])
758
+ const edits = []
759
+ const restore = (start, end, text) => edits.push({ start, end, text, mappings: [{
760
+ generatedStart: 0, generatedEnd: text.length, originalStart: start, originalEnd: end,
761
+ }] })
762
+ for (const comment of lowered.comments) {
763
+ const kept = preserved.get(comment.value)
764
+ if (kept && !kept.accessor) restore(comment.start, comment.end, kept.text)
765
+ }
766
+ eachNode(lowered, node => {
767
+ if (node.type !== 'ClassMethod') return
768
+ const kept = preserved.get(node.key.name)
769
+ if (kept?.accessor) restore(node.start, node.end, kept.text)
770
+ })
771
+ for (const node of lowered.program.body) {
772
+ if (node.type === 'ExportNamedDeclaration' && node.declaration?.declarations?.[0]?.id.name === marker) {
773
+ edits.push({ start: node.start, end: node.end, text: '' })
774
+ }
775
+ if (node.type !== 'ImportDeclaration' || node.source.value !== 'tslib'
776
+ || emittedMap.findEntry(node.loc.start.line - 1, node.loc.start.column).originalLine !== undefined
777
+ || !node.specifiers.every(specifier => specifier.imported?.name in legacyDecoratorHelpers)) continue
778
+ const helpers = node.specifiers.map(specifier => {
779
+ const name = specifier.local.name
780
+ internalBindings.add(name)
781
+ const helper = parse(`(${legacyDecoratorHelpers[specifier.imported.name].toString()})`, PARSER_OPTIONS)
782
+ traverseScopes(helper, { Identifier(path) {
783
+ if (!['Object', 'Reflect'].includes(path.node.name) || !path.isReferencedIdentifier()) return
784
+ path.replaceWith(babelTypes.memberExpression(babelTypes.identifier(intrinsics), babelTypes.identifier(path.node.name)))
785
+ path.skip()
786
+ } })
787
+ const declaration = helper.program.body[0].expression
788
+ if (target === 'module') {
789
+ declaration.type = 'FunctionDeclaration'
790
+ declaration.id = babelTypes.identifier(name)
791
+ deferredHelpers.set(name, generate(declaration).code)
792
+ } else deferredHelpers.set(name, `const ${name}=${generate(declaration).code};`)
793
+ return `const ${name}=void 0;`
794
+ }).join('\n')
795
+ edits.push({ start: node.start, end: node.end, text: `const ${intrinsics}=void 0;\n` + helpers })
796
+ }
797
+ applied = applySourceEdits(applied.code, applied.sourceMap, edits)
798
+ if (expressionClasses.size) {
799
+ const expressionEdits = []
800
+ eachNode(parseRecovered(applied.code), node => {
801
+ if (node.type !== 'ClassExpression' && node.type !== 'ClassDeclaration') return
802
+ const metadata = expressionClasses.get(node.id?.name)
803
+ if (!metadata) return
804
+ const inferred = metadata.originalName === undefined
805
+ const object = allocate('legacy_class_value')
806
+ internalBindings.add(object)
807
+ const keyPrefix = metadata.inferredKey
808
+ ? `((${object})=>${object}[${intrinsics}.Object.getOwnPropertyNames(${object})[0]??${intrinsics}.Object.getOwnPropertySymbols(${object})[0]])({[${metadata.inferredKey}]:`
809
+ : `({[${JSON.stringify(metadata.inferredName)}]:`
810
+ const prefix = (node.type === 'ClassDeclaration' ? `let ${node.id.name}=` : '') + (inferred ? keyPrefix : '(')
811
+ const suffix = (inferred ? metadata.inferredKey ? '})' : `})[${JSON.stringify(metadata.inferredName)}]` : ')')
812
+ + (node.type === 'ClassDeclaration' ? ';' : '')
813
+ expressionEdits.push({ start: node.start, end: node.start, text: prefix },
814
+ { start: node.id.start, end: node.id.end, text: metadata.originalName ?? (metadata.retainSelf ? node.id.name : '') },
815
+ { start: node.end, end: node.end, text: suffix })
816
+ if (metadata.retainSelf) {
817
+ const displayName = metadata.inferredKey
818
+ ? `({[${metadata.inferredKey}]:class{}})[${metadata.inferredKey}].name`
819
+ : JSON.stringify(metadata.inferredName)
820
+ expressionEdits.push({ start: node.body.start + 1, end: node.body.start + 1,
821
+ text: `static{if(${intrinsics}.Object.getOwnPropertyDescriptor(this,"name")?.value===${JSON.stringify(node.id.name)})${intrinsics}.Object.defineProperty(this,"name",{value:${displayName}})}` })
822
+ }
823
+ })
824
+ applied = applySourceEdits(applied.code, applied.sourceMap, expressionEdits)
825
+ }
826
+ // Suspension scaffolds are never executed. Restore their statements to the
827
+ // original expression so await/yield retain their native continuation points.
828
+ while ([...expressionClasses.values()].some(metadata => metadata.suspending)) {
829
+ const tree = parse(applied.code, { ...PARSER_OPTIONS, errorRecovery: true, allowSuperOutsideMethod: true })
830
+ let selected
831
+ traverseScopes(tree, { noScope: true, CallExpression: { exit(path) {
832
+ const body = path.node.callee.body
833
+ if (selected || !body || body.type !== 'BlockStatement') return
834
+ const returned = body.body.at(-1)
835
+ if (returned?.type === 'ReturnStatement' && expressionClasses.get(returned.argument?.name)?.suspending) selected = path
836
+ } } })
837
+ if (!selected) break
838
+ const body = selected.node.callee.body.body
839
+ const metadata = expressionClasses.get(body.at(-1).argument.name)
840
+ const declarations = []
841
+ const statements = body.map(statement => {
842
+ if (statement.type === 'VariableDeclaration') return { ...statement, kind: 'var' }
843
+ if (statement.type === 'ReturnStatement') return babelTypes.expressionStatement(statement.argument)
844
+ return statement
845
+ })
846
+ const expression = babelTypes.toSequenceExpression(statements, { push({ id }) { declarations.push(id) } })
847
+ const owner = selected.findParent(path => path.isBlockStatement() || path.isStaticBlock() || path.isProgram())
848
+ for (const identifier of declarations) internalBindings.add(identifier.name)
849
+ owner.node.body.unshift(babelTypes.variableDeclaration('let', declarations.map(id => babelTypes.variableDeclarator(id))))
850
+ selected.replaceWith(expression)
851
+ metadata.suspending = false
852
+ applied = mappedTransform(applied.code, applied.sourceMap, generate(tree,
853
+ { sourceMaps: true, sourceFileName: 'ptc-cell.ts' }, applied.code))
854
+ }
855
+ return { ...applied, internalBindings, deferredHelpers, internalPrivateNames }
856
+ }
857
+
858
+ /**
859
+ * Recover syntax first, then give Babel unique declaration occurrences to build
860
+ * scope facts without imposing JavaScript's repeated-declaration early errors.
861
+ * Logical names are grouped only after Babel has assigned their actual owners.
862
+ */
863
+ export function analyzeLogicalScopes(code, { target, parameterProperties, compact = false, compactNames = false, mutablePaths = false, onPhase } = {}) {
864
+ const tree = parse(code, { ...parserOptionsForTarget(target), errorRecovery: true, attachComment: !compact })
865
+ onPhase?.('scope-parsed')
866
+ // Read-only normalization owns exact UTF-16 ranges and its input map. The
867
+ // duplicated line/column objects are needed only by AST-generating clients.
868
+ if (compact) babelTypes.traverseFast(tree, node => { node.loc = undefined })
869
+ onPhase?.('scope-locations')
870
+ if (parameterProperties) eachNode(tree, node => {
871
+ if (node.type !== 'ClassMethod') return
872
+ parameterProperties.set(node, node.params.filter(parameter => parameter.type === 'TSParameterProperty'))
873
+ node.params = node.params.map(parameter => {
874
+ if (parameter.type !== 'TSParameterProperty') return parameter
875
+ parameter.parameter.decorators = parameter.decorators
876
+ return parameter.parameter
877
+ })
878
+ })
879
+ const invalidDelete=tree.errors.find(error=>error.reasonCode==='DeletePrivateField'||error.reasonCode==='StrictDelete')
880
+ if(invalidDelete) throw invalidDelete
881
+ const allocate = createGeneratedNameAllocator(tree, [], { compact: compactNames })
882
+ const occurrences = new Map()
883
+ const declarations = new Map()
884
+ const names = new Map()
885
+ const parameterExpressions = new Set()
886
+ const register = (node, declaration, role, declarator) => {
887
+ for (const binding of bindingNodes(node)) {
888
+ const occurrence = { node: binding, name: binding.name, declaration, declarator, role }
889
+ occurrences.set(binding, occurrence)
890
+ const list = declarations.get(declaration) ?? []
891
+ list.push(occurrence)
892
+ declarations.set(declaration, list)
893
+ names.set(binding, binding.name)
894
+ binding.name = allocate('scope_occurrence')
895
+ }
896
+ }
897
+ visitSource(tree, {
898
+ TSType(path) { path.skip() },
899
+ VariableDeclaration(path) {
900
+ for (const declarator of path.node.declarations) register(declarator.id, path.node, 'variable', declarator)
901
+ },
902
+ Function(path) {
903
+ const node = path.node
904
+ for (const parameter of node.params) eachNode(parameter, child => {
905
+ if (child.type === 'AssignmentPattern' || child.type === 'ObjectProperty' && child.computed) parameterExpressions.add(node)
906
+ })
907
+ if (node.id) register(node.id, node, node.type === 'FunctionDeclaration' ? 'function' : 'self')
908
+ for (const parameter of node.params) register(parameter.type === 'TSParameterProperty' ? parameter.parameter : parameter, node, 'parameter', parameter)
909
+ },
910
+ Class(path) {
911
+ if (path.node.id) register(path.node.id, path.node, path.isClassDeclaration() ? 'class' : 'self')
912
+ },
913
+ CatchClause(path) {
914
+ if (path.node.param) register(path.node.param, path.node, 'catch', path.node.param)
915
+ },
916
+ ImportDeclaration(path) {
917
+ for (const specifier of path.node.specifiers) register(specifier.local, path.node, 'import')
918
+ },
919
+ })
920
+ const scopes = new Map()
921
+ const functionSelfScopes = new Map()
922
+ const functionBodyScopes = new Map()
923
+ const { paths, owners } = analyzeSourceDeclarations(tree, declarations)
924
+ onPhase?.('scope-owners')
925
+ visitSource(tree, {
926
+ Identifier(path) {
927
+ const occurrence = occurrences.get(path.node)
928
+ if (occurrence === undefined) return
929
+ let scope = owners.get(path.node)
930
+ // Babel groups a named function's immutable self with its parameters and
931
+ // body declarations. The native self environment encloses both, so its
932
+ // identity must not participate in updates to a shadowing local binding.
933
+ if (occurrence.role === 'self' && occurrence.declaration.type === 'FunctionExpression') {
934
+ const self = { block: scope.block, parent: scope.parent }
935
+ functionSelfScopes.set(scope, self)
936
+ scope = self
937
+ }
938
+ const groups = scopes.get(scope) ?? new Map()
939
+ scopes.set(scope, groups)
940
+ const group = groups.get(occurrence.name) ?? { name: occurrence.name, scope, occurrences: [],
941
+ nativeInput: target === 'commonjs' && scope.block.type === 'Program' && (COMMONJS_PARAMETERS.includes(occurrence.name)
942
+ || occurrence.name === 'arguments' && occurrence.declaration.kind === 'var') }
943
+ groups.set(occurrence.name, group)
944
+ group.occurrences.push(occurrence)
945
+ occurrence.group = group
946
+ occurrence.scope = scope
947
+ },
948
+ })
949
+ for (const [scope, groups] of scopes) {
950
+ if (!parameterExpressions.has(scope.block)) continue
951
+ for (const group of [...groups.values()]) {
952
+ const parameters = group.occurrences.filter(item => item.role === 'parameter')
953
+ const body = group.occurrences.filter(item => item.role !== 'parameter')
954
+ // A valid var/function redeclaration after parameter expressions creates
955
+ // a body binding. Conflicting lexical declarations retain the selected
956
+ // stateful parameter-update policy instead.
957
+ if (!parameters.length || !body.length
958
+ || body.some(item => item.role !== 'function' && item.declaration.kind !== 'var')) continue
959
+ let bodyScope = functionBodyScopes.get(scope)
960
+ if (!bodyScope) {
961
+ bodyScope = { block: scope.block.body, parent: scope }
962
+ functionBodyScopes.set(scope, bodyScope)
963
+ scopes.set(bodyScope, new Map())
964
+ }
965
+ const local = { name: group.name, scope: bodyScope, occurrences: body, parameterSource: group }
966
+ scopes.get(bodyScope).set(group.name, local)
967
+ group.occurrences = parameters
968
+ for (const occurrence of body) {
969
+ occurrence.group = local
970
+ occurrence.scope = bodyScope
971
+ }
972
+ }
973
+ }
974
+ let emissionPaths = paths
975
+ if (mutablePaths) {
976
+ emissionPaths = new Map()
977
+ traverseScopes(tree, { enter(path) { emissionPaths.set(path.node, path) } })
978
+ }
979
+ return { tree, allocate, occurrences, declarations, names, scopes, functionSelfScopes, functionBodyScopes, paths: emissionPaths }
980
+ }
981
+
982
+ function annexBPromotions(facts, target) {
983
+ if (target === 'module') return []
984
+ const promotions = []
985
+ for (const groups of facts.scopes.values()) for (const group of groups.values()) {
986
+ if (facts.functionBodyScopes.get(group.scope.parent) === group.scope) continue
987
+ if (!['BlockStatement', 'SwitchStatement'].includes(group.scope.block.type)
988
+ || !group.occurrences.every(item => item.role === 'function'
989
+ && !item.declaration.async && !item.declaration.generator)) continue
990
+ if (facts.paths.get(group.occurrences[0].declaration).isInStrictMode()) continue
991
+ const owner = group.scope.getFunctionParent() ?? group.scope.getProgramParent()
992
+ let blocked = false
993
+ for (let scope = group.scope.parent; scope; scope = scope.parent) {
994
+ const outer = facts.scopes.get(scope)?.get(group.name)
995
+ const simpleCatch = outer?.occurrences.every(item => item.role === 'catch' && item.declaration.param.type === 'Identifier')
996
+ if (outer && !simpleCatch && (scope !== owner || outer.occurrences.some(item => item.role === 'parameter'
997
+ || item.role === 'import' || item.role === 'class'
998
+ || item.role === 'variable' && item.declaration.kind !== 'var'))) { blocked = true; break }
999
+ if (scope === owner) break
1000
+ }
1001
+ if (!blocked) promotions.push({ group, owner, outer: facts.scopes.get(owner)?.get(group.name) })
1002
+ }
1003
+ return promotions
1004
+ }
1005
+
1006
+ function prepareAnnexBBlocks(code, sourceMap, target, onPhase) {
1007
+ const program = parseRecovered(code)
1008
+ onPhase?.('annex-parsed')
1009
+ let promote = false
1010
+ if (target !== 'module') visitSource(program, { FunctionDeclaration(path) {
1011
+ if (path.node.async || path.node.generator || path.isInStrictMode() || path.parentPath.isProgram()
1012
+ || path.parentPath.isBlockStatement() && path.parentPath.parentPath.isFunction()) return
1013
+ promote = true
1014
+ path.stop()
1015
+ } })
1016
+ return { ...applySourceEdits(code, sourceMap, annexBBlockEdits(program)),
1017
+ promote }
1018
+ }
1019
+
1020
+ function introduceAnnexBVars(code, sourceMap, target, onPhase) {
1021
+ const blocks = prepareAnnexBBlocks(code, sourceMap, target, onPhase)
1022
+ onPhase?.('annex-blocks')
1023
+ if (!blocks.promote) return blocks
1024
+ code = blocks.code
1025
+ sourceMap = blocks.sourceMap
1026
+ const facts = analyzeLogicalScopes(code, { target, compact: true, onPhase })
1027
+ const missing = new Map()
1028
+ for (const promotion of annexBPromotions(facts, target)) {
1029
+ if (promotion.outer) continue
1030
+ const names = missing.get(promotion.owner) ?? new Map()
1031
+ names.set(promotion.group.name, promotion.group.occurrences[0].node)
1032
+ missing.set(promotion.owner, names)
1033
+ }
1034
+ const edits = []
1035
+ for (const [owner, names] of missing) {
1036
+ const node = owner.block.type === 'Program' ? owner.block : owner.block.body
1037
+ const start = node.directives?.at(-1)?.end ?? (node.type === 'Program' ? 0 : node.start + 1)
1038
+ const text = '\n' + [...names.keys()].map(name => `var ${name};`).join('') + '\n'
1039
+ edits.push({ start, end: start, text, mappings: [...names].map(([name, binding]) => ({
1040
+ generatedStart: text.indexOf(`var ${name}`) + 4,
1041
+ generatedEnd: text.indexOf(`var ${name}`) + 4 + name.length,
1042
+ originalStart: binding.start, originalEnd: binding.end,
1043
+ })) })
1044
+ }
1045
+ return applySourceEdits(code, sourceMap, edits)
1046
+ }
1047
+
1048
+ /**
1049
+ * Later phases parse and execute the emitted text again, and an expression
1050
+ * rewrite can turn the reference that starts an expression statement into a
1051
+ * parenthesized token. Automatic semicolon insertion would then join it to the
1052
+ * previous statement, so make that boundary explicit before any rewrite runs.
1053
+ *
1054
+ * A later rewrite can emit such a leading token for an expression statement's
1055
+ * callable reference, a declaration protected module/CommonJS mode emits as
1056
+ * `(pattern = (init));` (including one wrapped in an export), an exported
1057
+ * declaration or default value, and a block-level function declaration the
1058
+ * scope planner republishes as a candidate assignment. Every such boundary is
1059
+ * made explicit before any rewrite runs. A statement the module phases delete
1060
+ * as a whole cannot own the separator, because that deletion removes a trailing
1061
+ * semicolon with it, so the separator is attached to the last statement that
1062
+ * survives.
1063
+ *
1064
+ * The pass is semantics-neutral and idempotent. It changes the compiled form
1065
+ * of a stateful-v1/protected-v1 cell, so a journal recorded with an earlier
1066
+ * build may no longer reproduce its recorded completion; that cell is then
1067
+ * unreconstructable and recovery contracts the frontier as designed.
1068
+ */
1069
+ export function preserveStatementBoundaries(code, sourceMap = identitySourceMap(code.length), parserOptions = {}) {
1070
+ let tree
1071
+ try {
1072
+ tree = parse(code, { ...PARSER_OPTIONS, ...parserOptions, errorRecovery: true })
1073
+ } catch {
1074
+ // Invalid source keeps its existing diagnostic owner; this pass only
1075
+ // protects boundaries the parser already proved.
1076
+ return { code, sourceMap }
1077
+ }
1078
+ // A parse error outside the recoverable set owns its diagnostic: inserting
1079
+ // anything would change the program that diagnostic describes.
1080
+ if (tree.errors.some(error => !RECOVERABLE_CELL_PARSE_ERRORS.has(error.reasonCode))) return { code, sourceMap }
1081
+ const edits = []
1082
+ // A later module phase deletes these statements as a whole, a trailing
1083
+ // semicolon included, and a reparsed `;` placed directly before the next
1084
+ // statement is itself absorbed as that deleted statement's terminator. The
1085
+ // separator therefore belongs to the last statement that survives.
1086
+ const removedAsWhole = node => node.type === 'ImportDeclaration'
1087
+ || node.type === 'ExportAllDeclaration'
1088
+ || node.type === 'ExportNamedDeclaration' && node.declaration === null
1089
+ || node.type === 'ExportDefaultDeclaration'
1090
+ // Every statement form a later rewrite can emit with a `(` first token.
1091
+ // A declaration-less export or an import is deleted rather than re-emitted,
1092
+ // so only a surviving or re-emitted statement needs the guard.
1093
+ const parenthesized = (node, blockLevel) => node.type === 'ExpressionStatement'
1094
+ || node.type === 'VariableDeclaration'
1095
+ || node.type === 'ExportNamedDeclaration' && node.declaration !== null
1096
+ || node.type === 'ExportDefaultDeclaration'
1097
+ || blockLevel && node.type === 'FunctionDeclaration'
1098
+ const list = (statements, directives, blockLevel) => {
1099
+ const entries = [...directives ?? [], ...statements]
1100
+ let survivor
1101
+ let guardedAt
1102
+ for (const next of entries) {
1103
+ if (parenthesized(next, blockLevel) && survivor !== undefined && survivor.end !== guardedAt
1104
+ && code[survivor.end - 1] !== ';' && code[survivor.end] !== ';') {
1105
+ edits.push({ start: survivor.end, end: survivor.end, text: ';' })
1106
+ guardedAt = survivor.end
1107
+ }
1108
+ if (!removedAsWhole(next)) survivor = next
1109
+ }
1110
+ }
1111
+ const walk = node => {
1112
+ if (node.type === 'Program') list(node.body, node.directives, false)
1113
+ else if (node.type === 'BlockStatement' || node.type === 'StaticBlock') list(node.body, node.directives, true)
1114
+ else if (node.type === 'SwitchCase') list(node.consequent, undefined, true)
1115
+ for (const key of babelTypes.VISITOR_KEYS[node.type] ?? []) {
1116
+ const child = node[key]
1117
+ if (Array.isArray(child)) { for (const value of child) if (value?.type !== undefined) walk(value) }
1118
+ else if (child?.type !== undefined) walk(child)
1119
+ }
1120
+ }
1121
+ walk(tree.program)
1122
+ return edits.length === 0 ? { code, sourceMap } : applySourceEdits(code, sourceMap, edits)
1123
+ }
1124
+
1125
+ /**
1126
+ * stateful-v1 local activations use stable cells. A declaration evaluates into
1127
+ * candidate cells and links them to the committed identity only on success.
1128
+ * Escaped candidate closures consequently retain failed candidates, while a
1129
+ * successful candidate follows later writes to the original identity.
1130
+ * The root compiler owns Program bindings and calls this pass after lowering
1131
+ * those declarations. protected-v1 keeps native local binding policy.
1132
+ */
1133
+ export function normalizeStatefulScopes(code, sourceMap = identitySourceMap(code.length), options = {}) {
1134
+ const { outputPlan, ...metadata } = normalizeStatefulScopeInput(code, sourceMap, options)
1135
+ let result = metadata
1136
+ if (outputPlan) {
1137
+ // Release declaration ASTs and scope ancestry before materializing the
1138
+ // expanded output. This phase retains only numeric pieces and source facts.
1139
+ const { pieces, root, code, sourceMap, regionFacts } = outputPlan
1140
+ options.onPhase?.('mapping')
1141
+ const output = pieces.emit(root)
1142
+ result = { ...metadata, ...applySourceEdits(code, sourceMap,
1143
+ [{ start: 0, end: code.length, ...output }]),
1144
+ sourceRegions: { ...regionFacts, regions: output.regions } }
1145
+ }
1146
+ options.onPhase?.('validation')
1147
+ if (options.target === 'module' || options.target === 'commonjs') validateRegionSource(result, parserOptionsForTarget(options.target))
1148
+ result = options.deferDecorators ? result : lowerStatefulDecorators(result, options.target, options.intrinsicContext)
1149
+ return options.deferResources ? result : lowerStatefulResources(result, options)
1150
+ }
1151
+
1152
+ /** Resource lifetime is lowered only after declaration owners have consumed
1153
+ * the original lexical kind. Babel places lifetime boundaries; the shared
1154
+ * resource emitter keeps source operations in their owning activation. */
1155
+ export function lowerStatefulResources(result, { target, nativeUsing = supportsNativeUsing(), intrinsicContext } = {}) {
1156
+ if (nativeUsing || result.sourceRegions?.resources === false || !result.code.includes('using')) return result
1157
+ const parserOpts = parserOptionsForTarget(target)
1158
+ const tree = parse(result.code, parserOpts)
1159
+ let resources = false
1160
+ eachNode(tree, node => {
1161
+ if (node.type === 'VariableDeclaration' && (node.kind === 'using' || node.kind === 'await using')) resources = true
1162
+ })
1163
+ if (!resources) return result
1164
+ const allocate = createGeneratedNameAllocator(tree)
1165
+ const intrinsics = allocate('resource_intrinsics')
1166
+ const internalBindings = new Set(result.internalBindings)
1167
+ internalBindings.add(intrinsics)
1168
+ const intrinsicNames = new Set(['Object', 'TypeError', 'Error', 'Symbol', 'Promise', 'SuppressedError'])
1169
+ const ownsFrame = node => {
1170
+ let found = false
1171
+ eachNode(node, child => {
1172
+ if (child.type === 'VariableDeclarator' && child.id.name === result.rootFrameBinding) found = true
1173
+ })
1174
+ return found
1175
+ }
1176
+ const transformed = transformFromAstSync(tree, result.code, {
1177
+ filename: 'ptc-resource.js', babelrc: false, configFile: false, browserslistConfigFile: false, sourceMaps: true, parserOpts,
1178
+ cloneInputAst: false,
1179
+ plugins: [() => ({ pre(file) {
1180
+ // Keep the head's native lexical environment while expressing async
1181
+ // disposal as a body lifetime supported by the maintained lowerer.
1182
+ file.path.traverse({ ForOfStatement(path) {
1183
+ const { left } = path.node
1184
+ if (!babelTypes.isVariableDeclaration(left, { kind: 'await using' })) return
1185
+ const resource = babelTypes.identifier(allocate('iteration_resource'))
1186
+ const acquired = babelTypes.cloneNode(left.declarations[0].id)
1187
+ left.kind = 'const'
1188
+ path.node.body = babelTypes.blockStatement([
1189
+ babelTypes.variableDeclaration('await using', [babelTypes.variableDeclarator(resource, acquired)]),
1190
+ path.node.body,
1191
+ ])
1192
+ } })
1193
+ if (file.ast.program.sourceType !== 'module' && file.ast.program.body.some(node =>
1194
+ node.type === 'VariableDeclaration' && (node.kind === 'using' || node.kind === 'await using'))) {
1195
+ file.ast.program.body = [babelTypes.blockStatement(file.ast.program.body)]
1196
+ }
1197
+ } }), resourceTransform, () => ({ post(file) {
1198
+ lowerResourceOperations(file, intrinsics, allocate)
1199
+ file.path.traverse(generatedHelperOperations(intrinsics, intrinsicNames))
1200
+ for (const binding of Object.values(file.scope.bindings)) {
1201
+ if (!binding.identifier.loc) internalBindings.add(binding.identifier.name)
1202
+ }
1203
+ if (result.rootFrameBinding !== undefined) {
1204
+ const frame = file.ast.program.body.find(ownsFrame)
1205
+ const helpers = file.ast.program.body.filter(statement => statement !== frame && statement.type !== 'EmptyStatement')
1206
+ file.ast.program.body = [babelTypes.blockStatement([...helpers.map(statement => {
1207
+ if (!babelTypes.isFunctionDeclaration(statement)) return statement
1208
+ const value = babelTypes.toExpression(statement)
1209
+ return babelTypes.variableDeclaration('const', [babelTypes.variableDeclarator(babelTypes.cloneNode(value.id), value)])
1210
+ }), frame])]
1211
+ }
1212
+ } })],
1213
+ })
1214
+ const applied = mappedSourceTransform(result.code, result.sourceMap, transformed)
1215
+ const parsed = parse(applied.code, parserOpts)
1216
+ const offset = result.rootFrameBinding === undefined ? parsed.program.directives.at(-1)?.end ?? 0
1217
+ : parsed.program.body[0].start + 1
1218
+ const output = applySourceEdits(applied.code, applied.sourceMap, [
1219
+ { start: offset, end: offset, text: '\n' + intrinsicBootstrap(intrinsics, target, intrinsicContext) },
1220
+ ])
1221
+ return { ...result, ...output, internalBindings,
1222
+ ...(result.sourceRegions === undefined ? {} : { sourceRegions: indexSourceRegions(output.code, parserOpts) }) }
1223
+ }
1224
+
1225
+ export function hasModuleResources(code) {
1226
+ return code.includes('using') && parse(code, parserOptionsForTarget('module')).program.body.some(node =>
1227
+ node.type === 'VariableDeclaration' && (node.kind === 'using' || node.kind === 'await using'))
1228
+ }
1229
+
1230
+ function normalizeStatefulScopeInput(code, sourceMap, { mode = 'stateful-v1', target, moduleImport, intrinsicContext, onPhase,
1231
+ nativeJavaScript = false, nativeUsing = supportsNativeUsing() } = {}) {
1232
+ if (mode !== 'stateful-v1' && mode !== 'protected-v1') throw new TypeError('ptc-plus: unsupported scope semantics')
1233
+ onPhase?.('typescript')
1234
+ const typescript = nativeJavaScript ? { code, sourceMap }
1235
+ : lowerLegacyParameterDecorators(normalizeTypeScriptValues(code,sourceMap,target),target,intrinsicContext)
1236
+ const separated = preserveStatementBoundaries(typescript.code, typescript.sourceMap, parserOptionsForTarget(target))
1237
+ code=separated.code
1238
+ sourceMap=separated.sourceMap
1239
+ const finish = result => {
1240
+ result = { ...result, deferredHelpers: typescript.deferredHelpers,
1241
+ internalBindings: new Set([...typescript.internalBindings ?? [], ...result.internalBindings ?? []]) }
1242
+ return result
1243
+ }
1244
+ // Acquisition bindings own lifetime independently of exported identities.
1245
+ // Shared module cells retain lexical policy across native disposal, fallback
1246
+ // try regions and cyclic linking, without exporting a native using binding.
1247
+ const protectedModule = mode === 'protected-v1' && target === 'module' && hasModuleResources(code)
1248
+ const protectedCommonJs = mode === 'protected-v1' && target === 'commonjs'
1249
+ if (mode === 'protected-v1' && !protectedModule && !protectedCommonJs) return finish({ code, sourceMap })
1250
+ if (protectedCommonJs) {
1251
+ const parserOptions = parserOptionsForTarget(target)
1252
+ const tree = parse(code, parserOptions)
1253
+ let compilerBinding = false
1254
+ // A declaration-free name cannot shadow bootstrap. Prove that absence
1255
+ // from binding positions before allocating logical scope ancestry. If any
1256
+ // declaration might bind it, the complete scope planner decides ownership.
1257
+ eachNode(tree, node => {
1258
+ const patterns = node.type === 'VariableDeclarator' ? [node.id]
1259
+ : babelTypes.isFunction(node) ? [node.id, ...node.params]
1260
+ : babelTypes.isClass(node) ? [node.id]
1261
+ : node.type === 'CatchClause' ? [node.param] : []
1262
+ for (const pattern of patterns) {
1263
+ if (pattern && bindingNodes(pattern).some(binding => commonJsCompilerGlobals.has(binding.name))) compilerBinding = true
1264
+ }
1265
+ })
1266
+ if (!compilerBinding) return finish({ code, sourceMap, sourceRegions: indexSourceRegions(code, parserOptions, tree) })
1267
+ }
1268
+ onPhase?.('annex')
1269
+ const annex = introduceAnnexBVars(code, sourceMap, target, onPhase)
1270
+ code = annex.code
1271
+ sourceMap = annex.sourceMap
1272
+ onPhase?.('facts')
1273
+ const facts = analyzeLogicalScopes(code, { target, compact: true, compactNames: target === 'module' || target === 'commonjs', onPhase })
1274
+ onPhase?.('planning')
1275
+ const { tree, allocate, occurrences, scopes, paths } = facts
1276
+ const { decorated, resources, lexicalDynamic } = sourceFeatures(tree)
1277
+ const dynamicScopes = createDynamicScopeAnalysis(tree)
1278
+ const guardedBodies = singleStatementBodies(tree.program)
1279
+ const factory = allocate('local_cell')
1280
+ const intrinsics = allocate('local_intrinsics')
1281
+ const decoratorAdapter = allocate('member_decorator')
1282
+ const privateNames = allocate('private_names')
1283
+ const promotedFunctions = new Map(annexBPromotions(facts, target).flatMap(({ group, outer }) =>
1284
+ group.occurrences.map(item => [item.declaration, outer])))
1285
+ const protectedGroups = new Set()
1286
+ if (protectedCommonJs) {
1287
+ const root = [...scopes.values()].flatMap(scope => [...scope.values()])
1288
+ .filter(group => group.scope.block.type === 'Program')
1289
+ for (const group of root) if (commonJsCompilerGlobals.has(group.name)) protectedGroups.add(group)
1290
+ // A native declaration pattern owns all of its names together. Preserve
1291
+ // that ownership when only one name conflicts with bootstrap inputs.
1292
+ for (const group of protectedGroups) {
1293
+ const declarations = new Set(group.occurrences.map(item => item.declaration))
1294
+ for (const peer of root) if (peer.occurrences.some(item => declarations.has(item.declaration))) protectedGroups.add(peer)
1295
+ }
1296
+ if (protectedGroups.size === 0) return finish({ code, sourceMap,
1297
+ sourceRegions: indexSourceRegions(code, parserOptionsForTarget(target)) })
1298
+ }
1299
+ const groups = [...scopes.values()].flatMap(scope => [...scope.values()])
1300
+ .filter(group => (target === 'module' || target === 'commonjs' || group.scope.block.type !== 'Program')
1301
+ && !group.occurrences.some(item => item.role === 'self')
1302
+ && !(group.scope.block.type === 'Program' && typescript.internalBindings?.has(group.name))
1303
+ && (!protectedCommonJs || protectedGroups.has(group))
1304
+ && (!protectedModule || group.scope.block.type === 'Program' && group.occurrences.every(item =>
1305
+ item.role === 'class' || item.role === 'variable' && item.declaration.kind !== 'var')))
1306
+ const active = new Set(groups)
1307
+ const introductions = new Map()
1308
+ const declarationGroups = new Map()
1309
+ const parameterNames = new Map()
1310
+ const dynamicBindings = []
1311
+ const compilerLocalBindings = new Set()
1312
+ const rootPublications = new Map()
1313
+ const referenceCells = new Set()
1314
+ let varReferenceMarker
1315
+ const varReference = () => {
1316
+ if (!varReferenceMarker) {
1317
+ varReferenceMarker = allocate('var_reference')
1318
+ compilerLocalBindings.add(varReferenceMarker)
1319
+ dynamicBindings.push({ physicalName: varReferenceMarker, role: 'var-reference' })
1320
+ }
1321
+ return varReferenceMarker
1322
+ }
1323
+ const moduleExports = new Map()
1324
+ const importNames = new Map()
1325
+ const defaultExports = new Map()
1326
+ const labels = new Map()
1327
+ const jumps = new Map()
1328
+ const replacedConstructors = new Set()
1329
+ const privateClasses = new Map()
1330
+ const privateDeclarations = new Map()
1331
+ const privateMembers = new Map()
1332
+ const privateAccesses = new Map()
1333
+ const privateBrands = new Map()
1334
+ const decoratorContexts = new Map()
1335
+ visitSource(tree, {
1336
+ LabeledStatement(path) { labels.set(path.node, allocate('local_label')) },
1337
+ 'BreakStatement|ContinueStatement'(path) {
1338
+ if (path.node.label === null) return
1339
+ const owner = path.findParent(parent => parent.isLabeledStatement() && parent.node.label.name === path.node.label.name)
1340
+ if (owner) jumps.set(path.node, owner.node)
1341
+ },
1342
+ ClassBody(path) {
1343
+ const implementations = path.node.body.filter(member => member.type === 'ClassMethod' && member.kind === 'constructor' && member.body)
1344
+ for (const member of implementations.slice(0,-1)) replacedConstructors.add(member)
1345
+ const publicMethods = new Map()
1346
+ for (const member of path.node.body) {
1347
+ if (member.type !== 'ClassMethod' || member.kind === 'constructor'
1348
+ || member.computed && !['StringLiteral', 'NumericLiteral'].includes(member.key.type)) continue
1349
+ const name = member.key.name ?? String(member.key.value)
1350
+ const key = `${member.static}:${name}`
1351
+ const members = publicMethods.get(key) ?? []
1352
+ members.push(member)
1353
+ publicMethods.set(key, members)
1354
+ }
1355
+ for (const members of publicMethods.values()) {
1356
+ if (members.length < 2 || !members.some(member => member.decorators?.length)) continue
1357
+ let selected = new Map()
1358
+ for (const member of members) {
1359
+ const accessor = member.kind === 'get' || member.kind === 'set'
1360
+ if (!accessor || ![...selected.keys()].every(kind => kind === 'get' || kind === 'set')) selected = new Map()
1361
+ selected.set(accessor ? member.kind : 'value', member)
1362
+ }
1363
+ const kept = new Set(selected.values())
1364
+ for (const member of members) {
1365
+ if (kept.has(member)) continue
1366
+ const physical = allocate('decorated_effect')
1367
+ privateMembers.set(member, { physical, public: true })
1368
+ for (const decorator of member.decorators ?? []) decoratorContexts.set(decorator, {
1369
+ name: member.key.name ?? String(member.key.value), private: false,
1370
+ })
1371
+ }
1372
+ }
1373
+ const grouped = new Map()
1374
+ for (const member of path.node.body) {
1375
+ if (member.key?.type !== 'PrivateName') continue
1376
+ const name = member.key.id.name
1377
+ const group = grouped.get(name) ?? { name, members: [], targets: new Map() }
1378
+ grouped.set(name,group)
1379
+ group.members.push(member)
1380
+ const owner = group.targets.get(member.static) ?? { static: member.static, members: [] }
1381
+ group.targets.set(member.static,owner)
1382
+ owner.members.push(member)
1383
+ }
1384
+ const groups = [...grouped.values()].filter(group => group.members.length > 1
1385
+ && !(group.members.length === 2 && group.targets.size === 1
1386
+ && new Set(group.members.map(member=>member.kind)).has('get')
1387
+ && new Set(group.members.map(member=>member.kind)).has('set')))
1388
+ privateDeclarations.set(path.parent,new Set(grouped.keys()))
1389
+ if (groups.length === 0) return
1390
+ const classNode = path.parent
1391
+ const plan = { node: classNode, groups: new Map() }
1392
+ privateClasses.set(classNode,plan)
1393
+ for (const group of groups) {
1394
+ plan.groups.set(group.name,group)
1395
+ for (const owner of group.targets.values()) {
1396
+ owner.physical = group.targets.size===1?group.name:allocate('private_member')
1397
+ let selected = new Map()
1398
+ for (const member of owner.members) {
1399
+ const accessor = member.kind === 'get' || member.kind === 'set'
1400
+ if (!accessor || ![...selected.keys()].every(kind=>kind==='get'||kind==='set')) selected = new Map()
1401
+ selected.set(accessor ? member.kind : 'value',member)
1402
+ }
1403
+ owner.selected = new Set(selected.values())
1404
+ if(owner.physical!==group.name&&[...owner.selected].some(member=>member.type==='ClassPrivateMethod'&&member.kind==='method'&&!member.decorators?.length)) {
1405
+ owner.nameReady=true
1406
+ }
1407
+ owner.last = owner.members.at(-1).start
1408
+ for (const member of owner.members) {
1409
+ const physical = owner.selected.has(member) ? owner.physical
1410
+ : member.type === 'ClassPrivateProperty' || member.type === 'ClassAccessorProperty' || member.decorators?.length
1411
+ ? allocate('private_effect') : undefined
1412
+ privateMembers.set(member, { physical })
1413
+ if (physical !== group.name) for (const decorator of member.decorators ?? []) {
1414
+ decoratorContexts.set(decorator, { name: '#' + group.name, private: true })
1415
+ }
1416
+ }
1417
+ }
1418
+ }
1419
+ },
1420
+ })
1421
+ visitSource(tree,{
1422
+ 'MemberExpression|OptionalMemberExpression'(path) {
1423
+ if(path.node.property.type!=='PrivateName') return
1424
+ const owner=path.findParent(parent=>parent.isClass()&&privateDeclarations.get(parent.node)?.has(path.node.property.id.name))
1425
+ const group=owner&&privateClasses.get(owner.node)?.groups.get(path.node.property.id.name)
1426
+ if(group) privateAccesses.set(path.node,group)
1427
+ },
1428
+ BinaryExpression(path) {
1429
+ if(path.node.operator!=='in'||path.node.left.type!=='PrivateName') return
1430
+ const owner=path.findParent(parent=>parent.isClass()&&privateDeclarations.get(parent.node)?.has(path.node.left.id.name))
1431
+ const group=owner&&privateClasses.get(owner.node)?.groups.get(path.node.left.id.name)
1432
+ if(group) privateBrands.set(path.node,group)
1433
+ },
1434
+ })
1435
+ for (const group of groups) {
1436
+ group.cell = allocate('local_binding')
1437
+ group.occurrences.sort((a, b) => a.node.start - b.node.start)
1438
+ const parameters = group.occurrences.filter(item => item.role === 'parameter' || item.role === 'catch')
1439
+ for (const item of parameters) parameterNames.set(item.node, allocate('local_parameter'))
1440
+ group.parameter = parameters.at(-1)
1441
+ const kind = group.parameter || group.nativeInput ? 'param' : group.occurrences[0].declaration.kind
1442
+ ?? (group.occurrences[0].role === 'function' ? 'hoisted' : 'let')
1443
+ group.readOnly = mode === 'protected-v1' && ['const', 'using', 'await using'].includes(kind)
1444
+ for (const parameter of parameters) {
1445
+ const physicalName = parameterNames.get(parameter.node)
1446
+ if (typescript.internalBindings?.has(group.name)) compilerLocalBindings.add(physicalName)
1447
+ else dynamicBindings.push({ physicalName, name: group.name, kind: 'param', role: 'parameter',
1448
+ scopeStart: group.scope.block.start, scopeEnd: group.scope.block.end })
1449
+ }
1450
+ for (const item of group.occurrences.filter(item => item.role === 'import')) {
1451
+ const physicalName = allocate('local_import')
1452
+ importNames.set(item.node, physicalName)
1453
+ compilerLocalBindings.add(physicalName)
1454
+ }
1455
+ group.hoistedDeclaration = group.occurrences.filter(item => item.role === 'function').at(-1)?.declaration
1456
+ group.hoisted = group.hoistedDeclaration !== undefined && group.occurrences.every(item =>
1457
+ item.role === 'function' || item.role === 'parameter' || item.declaration.kind === 'var')
1458
+ if (target === 'module' && group.scope.block.type === 'Program') {
1459
+ group.publicName = allocate('module_binding')
1460
+ group.accessor = group.cell
1461
+ group.storage = allocate('module_record')
1462
+ group.cell = `${group.accessor}()`
1463
+ if (group.hoisted) group.publicName = group.name
1464
+ group.nativeLexical = !group.hoisted && !group.occurrences.some(item => item.role === 'import' || item.declaration.kind === 'var')
1465
+ compilerLocalBindings.add(group.storage)
1466
+ }
1467
+ if (group.publicName && !group.hoisted) compilerLocalBindings.add(group.publicName)
1468
+ const physicalName = group.accessor ?? group.cell
1469
+ if (typescript.internalBindings?.has(group.name)) compilerLocalBindings.add(physicalName)
1470
+ else dynamicBindings.push({ physicalName, name: group.name, kind, property: 'v',
1471
+ ...(group.accessor ? { accessor: true } : {}),
1472
+ role: 'binding', scopeStart: group.scope.block.start, scopeEnd: group.scope.block.end })
1473
+ const owner = group.scope.block
1474
+ const list = introductions.get(owner) ?? []
1475
+ list.push(group)
1476
+ introductions.set(owner, list)
1477
+ for (const item of group.occurrences) {
1478
+ const list = declarationGroups.get(item.declaration) ?? new Set()
1479
+ list.add(group)
1480
+ declarationGroups.set(item.declaration, list)
1481
+ }
1482
+ }
1483
+ if (target === 'module') {
1484
+ for (const statement of tree.program.body) {
1485
+ if (statement.type === 'ExportDefaultDeclaration') {
1486
+ const declaration = statement.declaration
1487
+ if (declaration.type === 'FunctionDeclaration' && declaration.id === null) {
1488
+ defaultExports.set(statement, { native: true })
1489
+ continue
1490
+ }
1491
+ const originalGroup = declaration.id ? occurrences.get(declaration.id)?.group : undefined
1492
+ const group = active.has(originalGroup) ? originalGroup : undefined
1493
+ if (protectedModule && declaration.type === 'FunctionDeclaration') {
1494
+ defaultExports.set(statement, { native: true })
1495
+ continue
1496
+ }
1497
+ const exported = group ?? { publicName: allocate('module_default') }
1498
+ defaultExports.set(statement, { group, exported })
1499
+ moduleExports.set('default', exported)
1500
+ continue
1501
+ }
1502
+ if (statement.type !== 'ExportNamedDeclaration' || statement.source) continue
1503
+ if (statement.declaration) {
1504
+ for (const occurrence of facts.declarations.get(statement.declaration) ?? []) {
1505
+ moduleExports.set(occurrence.name, active.has(occurrence.group) ? occurrence.group : { publicName: occurrence.name })
1506
+ }
1507
+ } else {
1508
+ for (const specifier of statement.specifiers) {
1509
+ const group = scopes.get(paths.scopeFor(statement))?.get(specifier.local.name)
1510
+ if (group) moduleExports.set(specifier.exported.name ?? specifier.exported.value,
1511
+ active.has(group) ? group : { publicName: specifier.local.name })
1512
+ }
1513
+ }
1514
+ }
1515
+ }
1516
+ if (groups.length === 0 && defaultExports.size === 0 && labels.size === 0 && replacedConstructors.size === 0
1517
+ && privateClasses.size === 0 && privateMembers.size === 0) return finish({ code, sourceMap })
1518
+ const resolve = (path, name) => resolveSourceBinding(facts, path, name)
1519
+ const references = new Map()
1520
+ const initializerTargets = new Map()
1521
+ for (const occurrence of occurrences.values()) {
1522
+ if (occurrence.declaration.kind !== 'var') continue
1523
+ const target = varInitializerTarget(paths.get(occurrence.node), occurrence.scope.block,
1524
+ occurrence.name, node => facts.names.get(node))
1525
+ if (target.catchNode || target.withNodes.length) {
1526
+ initializerTargets.set(occurrence.node, { withDepth: target.withNodes.length,
1527
+ catchGroup: target.catchNode && occurrences.get(target.catchNode.param).group })
1528
+ }
1529
+ }
1530
+ const deferredDynamicReferences = new Set()
1531
+ const deleteOperands = new Map()
1532
+ visitSource(tree, {
1533
+ UnaryExpression(path) {
1534
+ if (path.node.operator !== 'delete') return
1535
+ let operand = path.node.argument
1536
+ while ((operand.type.startsWith('TS') || operand.type === 'ParenthesizedExpression') && operand.expression) operand = operand.expression
1537
+ if (operand.type === 'Identifier') deleteOperands.set(path.node, operand)
1538
+ },
1539
+ Identifier(path) {
1540
+ if (occurrences.has(path.node)) return
1541
+ if (!path.isReferencedIdentifier() && !path.isBindingIdentifier()) return
1542
+ const sourcePath = paths.get(path.node)
1543
+ const group = resolve(sourcePath, path.node.name)
1544
+ if (active.has(group)) {
1545
+ references.set(path.node, group)
1546
+ const withOwner = sourcePath.findParent(parent => parent.isWithStatement()
1547
+ && path.node.start >= parent.node.body.start
1548
+ && !(group.scope.block.start >= parent.node.body.start && group.scope.block.end <= parent.node.body.end))
1549
+ if (withOwner || dynamicScopes.mayEvalShadow(sourcePath, group.scope.block)) {
1550
+ deferredDynamicReferences.add(path.node)
1551
+ }
1552
+ }
1553
+ },
1554
+ })
1555
+ onPhase?.('references')
1556
+ const pieces = createSourcePieces(code)
1557
+ const { text: part, join, original, mapped } = pieces
1558
+ const empty = () => part('')
1559
+ const regionContext = node => {
1560
+ const path = paths.get(node)
1561
+ const owner = isFunctionNode(node) ? path : path.findParent(parent => parent.isFunction())
1562
+ const privateNames = new Set()
1563
+ const regionLabels = []
1564
+ for (let current = path; current; current = current.parentPath) {
1565
+ if (current.isClass()) {
1566
+ for (const name of privateDeclarations.get(current.node) ?? []) privateNames.add(name)
1567
+ for (const group of privateClasses.get(current.node)?.groups.values() ?? []) {
1568
+ for (const target of group.targets.values()) privateNames.add(target.physical)
1569
+ }
1570
+ }
1571
+ if (current.isLabeledStatement()) regionLabels.push(labels.get(current.node))
1572
+ }
1573
+ return { strict: path.isInStrictMode() || owner?.node.body.directives?.some(item => item.value.value === 'use strict'),
1574
+ async: owner?.node.async ?? target === 'module', generator: owner?.node.generator ?? false,
1575
+ labels: regionLabels, privateNames: [...privateNames], top: node.type === 'Program' }
1576
+ }
1577
+ const statementPieces = (values, node) => {
1578
+ if (values.length === 0) return empty()
1579
+ const chunks = []
1580
+ let pending = [], size = 0
1581
+ const flush = () => {
1582
+ const piece = join(pending)
1583
+ chunks.push(pieces.region(piece, { kind: 'statements', ...regionContext(node) }))
1584
+ pending = []; size = 0
1585
+ }
1586
+ for (const value of values) {
1587
+ pending.push(value)
1588
+ size += pieces.length(value)
1589
+ if (size >= 16384) flush()
1590
+ }
1591
+ if (pending.length) flush()
1592
+ return join(chunks)
1593
+ }
1594
+ const cellFor = (group, candidates) => candidates.get(group) ?? group.cell
1595
+ // A lazy cell may call its accessor. Keep that complete reference grouped
1596
+ // when source uses it as a constructor or the base of a constructor member.
1597
+ const read = (group, candidates) => {
1598
+ if (!active.has(group)) return `(${group.name})`
1599
+ const cell = cellFor(group, candidates)
1600
+ return referenceCells.has(cell) ? `(${cell}().value)` : `(${cell}.v)`
1601
+ }
1602
+ const parameterReference = (node, group) => {
1603
+ const owner = group.scope.block
1604
+ if (!isFunctionNode(owner) || node.start >= owner.body.start) return undefined
1605
+ const parameters = group.occurrences.filter(item=>item.role==='parameter').map(item=>parameterNames.get(item.node)).reverse()
1606
+ if(parameters.length===0) return undefined
1607
+ if(parameters.length===1) return parameters[0]
1608
+ const fallback=parameters.at(-1)
1609
+ const read=parameters.slice(0,-1).map(name=>`try{return ${name}}catch{}`).join('')+`return ${fallback}`
1610
+ const write=parameters.slice(0,-1).map(name=>`try{${name};${name}=value;return}catch{}`).join('')+`${fallback}=value`
1611
+ return `({get v(){${read}},set v(value){${write}}}).v`
1612
+ }
1613
+ const initialization = (group, candidates) => {
1614
+ if (group.publicName) {
1615
+ const imported = group.occurrences.filter(item => item.role === 'import').at(-1)
1616
+ const initial = group.hoisted ? group.publicName : 'void 0'
1617
+ let getter = imported ? `()=>${importNames.get(imported.node)}` : 'void 0'
1618
+ if (moduleImport && imported) {
1619
+ const specifier = imported.declaration.specifiers.find(specifier => specifier.local === imported.node)
1620
+ const name = specifier.type === 'ImportNamespaceSpecifier' ? null : specifier.type === 'ImportDefaultSpecifier' ? 'default'
1621
+ : specifier.imported.name ?? specifier.imported.value
1622
+ const attributes = Object.fromEntries((imported.declaration.attributes ?? [])
1623
+ .map(attribute => [attribute.key.name ?? attribute.key.value, attribute.value.value]))
1624
+ getter = `()=>${moduleImport}(${JSON.stringify(imported.declaration.source.value)},${JSON.stringify(name)},${getter},${JSON.stringify(attributes)})`
1625
+ }
1626
+ // Hoisted accessors expose the cell before evaluation. Creating a record
1627
+ // neither reads an import nor initializes a lexical source declaration.
1628
+ return part(`${group.hoisted || group.nativeLexical ? '' : `var ${group.publicName};`}var ${group.storage};function ${group.accessor}(){if(${group.storage})return ${group.storage};return ${group.storage}=${factory}(${JSON.stringify(group.name)},${initial},${!group.nativeLexical},${getter},void 0,${group.nativeLexical},${group.readOnly})}${group.cell};`)
1629
+ }
1630
+ if (group.parameter || group.nativeInput) {
1631
+ const bridge = group.nativeInput ? allocate('native_parameter') : undefined
1632
+ if (bridge) compilerLocalBindings.add(bridge)
1633
+ const name = group.parameter && parameterNames.get(group.parameter.node)
1634
+ const reference = bridge ? `${bridge}.get,${bridge}.set` : `()=>${name},v=>${name}=v`
1635
+ return join([...(bridge ? [part(`const ${bridge}={get:()=>${group.name},set:next=>${group.name}=next};`)] : []),
1636
+ part(`let ${group.cell}=${factory}(${JSON.stringify(group.name)},void 0,false,${reference});`),
1637
+ ...(group.hoisted ? [part(`${group.cell}.v=(`),
1638
+ emit(group.hoistedDeclaration, candidates, new Set([group.hoistedDeclaration])), part(');')] : [])])
1639
+ }
1640
+ if (group.hoisted) {
1641
+ const declaration = group.hoistedDeclaration
1642
+ return join([part(`let ${group.cell}=${factory}(${JSON.stringify(group.name)},(`),
1643
+ emit(declaration, candidates, new Set([declaration])), part('),true);')])
1644
+ }
1645
+ if (group.parameterSource) return part(`let ${group.cell}=${factory}(${JSON.stringify(group.name)},${read(group.parameterSource, candidates)},true);`)
1646
+ const hoistedVar = group.occurrences.some(item => item.declaration.kind === 'var')
1647
+ const owner = group.scope.block
1648
+ const initial = hoistedVar && group.name === 'arguments' && isFunctionNode(owner)
1649
+ && owner.type !== 'ArrowFunctionExpression' ? allocate('parameter_initial') : undefined
1650
+ if (initial !== undefined) {
1651
+ // The initial value belongs to the parameter environment, before the body
1652
+ // cell exists. Dynamic adaptation must not resolve it as a body reference.
1653
+ compilerLocalBindings.add(initial)
1654
+ dynamicBindings.push({ physicalName: initial, name: group.name, role: 'parameter-initializer' })
1655
+ }
1656
+ return part(`${initial === undefined ? '' : `const ${initial}=arguments;`}let ${group.cell}=${factory}(${JSON.stringify(group.name)},${initial ?? 'void 0'},${hoistedVar},void 0,void 0,${mode === 'protected-v1' && !hoistedVar},${group.readOnly});`)
1657
+ }
1658
+ const initializations = (node, candidates) => statementPieces((introductions.get(node) ?? []).map(group => initialization(group, candidates)), node)
1659
+ const emitPattern = (node, candidates) => {
1660
+ const result=emit(node,candidates)
1661
+ if(node.type==='Identifier'||!node.typeAnnotation) return result
1662
+ return pieces.slice(result, 0, pieces.length(result) - (node.end - node.typeAnnotation.start))
1663
+ }
1664
+ const emitInitializer = (node, candidates, name) => {
1665
+ let expression = node
1666
+ while ((expression.type.startsWith('TS') || expression.type === 'ParenthesizedExpression') && expression.expression) expression = expression.expression
1667
+ const anonymous = expression.type === 'ArrowFunctionExpression'
1668
+ || ['FunctionExpression', 'ClassExpression', 'ClassDeclaration', 'FunctionDeclaration'].includes(expression.type) && expression.id === null
1669
+ return anonymous && name !== undefined
1670
+ ? join([part(`({[${JSON.stringify(name)}]:(`), emit(node, candidates), part(`)})[${JSON.stringify(name)}]`)])
1671
+ : emit(node, candidates)
1672
+ }
1673
+ const declarator = (node, candidates, expression = false, iterationValue) => {
1674
+ const involved = [...new Set(bindingNodes(node.id).map(binding => occurrences.get(binding)?.group).filter(group => active.has(group)))]
1675
+ if (involved.length === 0) return expression ? emit(node, candidates)
1676
+ : join([part(paths.parentFor(node).kind + ' '), emit(node, candidates), part(';')])
1677
+ const lexical = involved.filter(group => group.nativeLexical && group.occurrences[0].node.start >= node.start
1678
+ && group.occurrences[0].node.end <= node.end)
1679
+ if (node.init === null && iterationValue === undefined) return part(lexical.map(group => `let ${group.publicName};`).join('')
1680
+ + involved.map(group => `${group.cell}.ensure()`).join(',') + (expression ? '' : ';'))
1681
+ const initializer = () => iterationValue ?? emitInitializer(node.init, candidates,
1682
+ node.id.type === 'Identifier' ? occurrences.get(node.id).name : undefined)
1683
+ if (mode === 'protected-v1') {
1684
+ // Native lexical patterns initialize each binding as its element is
1685
+ // reached. The readonly write path is distinct from initialization;
1686
+ // callbacks during later defaults can already observe earlier elements.
1687
+ const initializing = new Map(candidates)
1688
+ const declarations = []
1689
+ for (const binding of bindingNodes(node.id)) {
1690
+ const group = occurrences.get(binding)?.group
1691
+ if (!active.has(group)) continue
1692
+ const target = initializerTargets.get(binding)
1693
+ if (target?.withDepth) {
1694
+ const name = allocate('local_var_reference')
1695
+ const fallback = read(target.catchGroup ?? group, candidates)
1696
+ declarations.push(`${name}=()=>${varReference()}(${JSON.stringify(group.name)},${target.withDepth},{get:()=>${fallback},set:value=>${fallback}=value})`)
1697
+ compilerLocalBindings.add(name)
1698
+ referenceCells.add(name)
1699
+ initializing.set(target.catchGroup ?? group, name)
1700
+ } else if (!target?.catchGroup) initializing.set(group,
1701
+ `({get v(){return ${group.cell}.v},set v(value){${group.cell}.initialize(value)}})`)
1702
+ }
1703
+ const assignment = join([part('('), emitPattern(node.id, initializing), part('=('), initializer(), part('))')])
1704
+ return expression ? join([part(`${declarations.length ? declarations.join(',') + ',' : ''}${allocate('local_initialization')}=`), assignment])
1705
+ : join([part(declarations.length ? `{const ${declarations.join(',')};` : ''), assignment,
1706
+ part(declarations.length ? ';}' : ';')])
1707
+ }
1708
+ const targets = new Map(bindingNodes(node.id).map(binding =>
1709
+ [occurrences.get(binding)?.group, initializerTargets.get(binding)]))
1710
+ const stored = involved.filter(group => !targets.get(group)?.catchGroup)
1711
+ const candidateMap = new Map(candidates)
1712
+ const baseCandidates = new Map()
1713
+ const names = []
1714
+ for (const group of stored) {
1715
+ const name = allocate('local_candidate')
1716
+ if (typescript.internalBindings?.has(group.name) || targets.get(group)?.withDepth) compilerLocalBindings.add(name)
1717
+ else dynamicBindings.push({ physicalName: name, name: group.name, kind: 'let', property: 'v',
1718
+ role: 'candidate', linkPhysicalName: group.accessor ?? group.cell,
1719
+ ...(group.accessor ? { linkAccessor: true } : {}), scopeStart: node.start, scopeEnd: node.end,
1720
+ ...(node.init === null ? {} : { initializerStart: node.init.start, initializerEnd: node.init.end }),
1721
+ patternStart: node.id.start, patternEnd: node.id.end })
1722
+ candidateMap.set(group, name)
1723
+ baseCandidates.set(group, name)
1724
+ names.push(`${name}=${factory}(${JSON.stringify(group.name)},void 0,false,()=>${group.cell}.v)`)
1725
+ }
1726
+ for (const group of involved) {
1727
+ const target = targets.get(group)
1728
+ if (!target?.withDepth) continue
1729
+ const name = allocate('local_var_reference')
1730
+ const fallback = target.catchGroup ? read(target.catchGroup, candidates) : `${baseCandidates.get(group)}.v`
1731
+ names.push(`${name}=()=>${varReference()}(${JSON.stringify(group.name)},${target.withDepth},{get:()=>${fallback},set:value=>${fallback}=value})`)
1732
+ referenceCells.add(name)
1733
+ candidateMap.set(group, name)
1734
+ if (target.catchGroup) candidateMap.set(target.catchGroup, name)
1735
+ dynamicBindings.push({ physicalName: name, name: group.name, kind: 'let', role: 'candidate', reference: true, accessor: true,
1736
+ linkPhysicalName: group.accessor ?? group.cell, scopeStart: node.start, scopeEnd: node.end })
1737
+ }
1738
+ const candidateNames = stored.map(group => baseCandidates.get(group))
1739
+ const body = join([
1740
+ part(names.length ? `let ${names.join(',')};` : ''),
1741
+ part('('), emitPattern(node.id, candidateMap), part('=('),
1742
+ initializer(), part('));'),
1743
+ part(lexical.map(group => `let ${group.publicName}=${candidateMap.get(group)}.v;`).join('')),
1744
+ part(stored.map((group, index) => `${candidateNames[index]}.commit(${group.cell});`).join('')),
1745
+ ])
1746
+ if (expression) {
1747
+ return join([part(`${names.length ? names.join(',') + ',' : ''}${allocate('local_initialization')}=(`),
1748
+ part('('), emitPattern(node.id, candidateMap), part('=('),
1749
+ initializer(), part('))'),
1750
+ part(stored.map((group, index) => `,${candidateNames[index]}.commit(${group.cell})`).join('')), part(')')])
1751
+ }
1752
+ return lexical.length ? body : join([part('{'), body, part('}')])
1753
+ }
1754
+ const privateBridge = group => {
1755
+ const targets = [...group.targets.values()].sort((a,b)=>b.last-a.last)
1756
+ const branches = targets.map(owner => {
1757
+ const names = target === 'module' ? `(${privateNames}??=${intrinsics}.weakSetStore())` : privateNames
1758
+ const name = owner.nameReady ? `if(!${names}.has(receiver.#${owner.physical})){${intrinsics}.Object.defineProperty(receiver.#${owner.physical},"name",{value:${JSON.stringify('#'+group.name)},configurable:true});${privateNames}.add(receiver.#${owner.physical});}` : ''
1759
+ const setter = [...owner.selected].some(member => member.type === 'ClassPrivateMethod' && member.kind === 'method')
1760
+ ? `throw new ${intrinsics}.TypeError("Private method is not writable")` : `receiver.#${owner.physical}=value`
1761
+ return `if(#${owner.physical} in receiver){if(test)return true;${name}return {get v(){return receiver.#${owner.physical}},set v(value){${setter}},get call(){const fn=receiver.#${owner.physical};return fn==null?fn:(...args)=>${intrinsics}.Reflect.apply(fn,receiver,args)}}}`
1762
+ }).join('')
1763
+ // Private names themselves carry the class lexical environment. Keeping the
1764
+ // bridge there avoids manufacturing a class self-name and preserves native
1765
+ // inferred names even in delayed computed field initializers.
1766
+ return `((receiver,optional=false,test=false)=>{if(optional&&receiver==null)return void 0;${branches}if(test)return false;throw new ${intrinsics}.TypeError(${JSON.stringify(`Cannot access private member #${group.name} on this receiver`)})})`
1767
+ }
1768
+ const emit = (node, candidates = new Map(), suppress = new Set(), loopLabels = '') => {
1769
+ if (babelTypes.isTSType(node)) return original(node.start, node.end)
1770
+ if (node.type === 'Decorator') {
1771
+ const context = decoratorContexts.get(node)
1772
+ if (!context) return join([part('@('), emit(node.expression, candidates), part(')')])
1773
+ const tail = `,${JSON.stringify(context.name)},${context.private})`
1774
+ const expression = node.expression
1775
+ if (expression.type === 'MemberExpression') {
1776
+ const receiver = allocate('decorator_receiver')
1777
+ const key = allocate('decorator_key')
1778
+ return join([part(`@(((${receiver},${key})=>${decoratorAdapter}(${receiver}[${key}],${receiver}${tail})(`),
1779
+ emit(expression.object, candidates), part(','),
1780
+ expression.computed ? emit(expression.property, candidates) : part(JSON.stringify(expression.property.name)), part('))')])
1781
+ }
1782
+ return join([part(`@(${decoratorAdapter}(`), emit(expression, candidates), part(',void 0' + tail + ')')])
1783
+ }
1784
+ const member = paths.parentFor(node)
1785
+ if (privateMembers.get(member)?.public && member.key === node) {
1786
+ return mapped(`#${privateMembers.get(member).physical}`, node)
1787
+ }
1788
+ if(privateMembers.has(node)) {
1789
+ const plan=privateMembers.get(node)
1790
+ if(plan.physical===undefined) return part('')
1791
+ }
1792
+ if (replacedConstructors.has(node)) return part('')
1793
+ if (node.type === 'LabeledStatement') {
1794
+ let loop = node
1795
+ let prefix = ''
1796
+ while (loop.type === 'LabeledStatement') {
1797
+ prefix += `${labels.get(loop)}:`
1798
+ loop = loop.body
1799
+ }
1800
+ if ((loop.type === 'ForOfStatement' || loop.type === 'ForInStatement')
1801
+ && (introductions.has(loop) || declarationGroups.has(loop.left) && loop.left.declarations[0].init)) {
1802
+ return emit(loop, candidates, suppress, prefix)
1803
+ }
1804
+ return join([part(`${labels.get(node)}:`),emit(node.body,candidates)])
1805
+ }
1806
+ if (jumps.has(node)) return mapped(`${node.type === 'BreakStatement' ? 'break' : 'continue'} ${labels.get(jumps.get(node))};`,node)
1807
+ if(node.type==='PrivateName' && privateMembers.has(member)) {
1808
+ return mapped(`#${privateMembers.get(member).physical}`,node)
1809
+ }
1810
+ if(privateBrands.has(node)) {
1811
+ const group=privateBrands.get(node)
1812
+ return join([part(`${privateBridge(group)}((`),emit(node.right,candidates),part('),false,true)')])
1813
+ }
1814
+ if((node.type==='CallExpression'||node.type==='OptionalCallExpression')&&privateAccesses.has(node.callee)) {
1815
+ const member=node.callee
1816
+ const group=privateAccesses.get(member)
1817
+ return join([part(`${privateBridge(group)}((`),emit(member.object,candidates),
1818
+ part(`)${member.optional?',true':''})${member.optional?'?.':'.'}call${node.optional?'?.':''}(`),
1819
+ ...node.arguments.flatMap((argument,index)=>[...(index?[part(',')]:[]),emit(argument,candidates)]),part(')')])
1820
+ }
1821
+ if(node.type==='TaggedTemplateExpression'&&privateAccesses.has(node.tag)) {
1822
+ const group=privateAccesses.get(node.tag)
1823
+ return join([part(`${privateBridge(group)}((`),emit(node.tag.object,candidates),part(')).call'),emit(node.quasi,candidates)])
1824
+ }
1825
+ if(privateAccesses.has(node)) {
1826
+ const group=privateAccesses.get(node)
1827
+ return join([part(`(${privateBridge(group)}((`),emit(node.object,candidates),part(`)${node.optional?',true':''}))${node.optional?'?.':'.'}v`)])
1828
+ }
1829
+ if (deleteOperands.has(node)) {
1830
+ const operand = deleteOperands.get(node)
1831
+ if (paths.get(node).isInStrictMode()) {
1832
+ const position = mapSourcePosition({ line: 1, column: node.start + 1 }, code, code, identitySourceMap(code.length))
1833
+ throw Object.assign(new SyntaxError('Delete of an unqualified identifier in strict mode.'),
1834
+ { loc: { line: position.line, column: position.column - 1 } })
1835
+ }
1836
+ // Deleting a declarative reference never reads its value, even in TDZ.
1837
+ // With-object and eval-created references keep their dynamic owner.
1838
+ const group = references.get(operand)
1839
+ const candidate = candidates.get(group)
1840
+ if (referenceCells.has(candidate) && !dynamicScopes.mayEvalShadow(paths.get(operand), group.scope.block)) {
1841
+ return mapped(`${candidate}().delete()`, node)
1842
+ }
1843
+ if (references.has(operand) && !deferredDynamicReferences.has(operand)) return mapped('false', node)
1844
+ return join([mapped('delete (', node), emit(operand, candidates), part(')')])
1845
+ }
1846
+ if (node.type === 'Identifier') {
1847
+ const referenced = references.get(node)
1848
+ const candidate = candidates.get(referenced)
1849
+ if (deferredDynamicReferences.has(node) && (!referenceCells.has(candidate)
1850
+ || dynamicScopes.mayEvalShadow(paths.get(node), referenced.scope.block))) return original(node.start, node.end)
1851
+ if (node.name === 'eval' && member.type === 'CallExpression' && member.callee === node) return original(node.start, node.end)
1852
+ const occurrence = occurrences.get(node)
1853
+ if (active.has(occurrence?.group) && initializerTargets.has(node)) {
1854
+ return mapped(read(initializerTargets.get(node).catchGroup ?? occurrence.group, candidates), node)
1855
+ }
1856
+ if (importNames.has(node)) return mapped(importNames.get(node), node)
1857
+ if (parameterNames.has(node)) return mapped(parameterNames.get(node), node)
1858
+ const group = references.get(node) ?? (active.has(occurrence?.group) ? occurrence.group : undefined)
1859
+ if (group !== undefined && !(occurrence && ['function', 'class'].includes(occurrence.role))) {
1860
+ let text = parameterReference(node, group) ?? read(group, candidates)
1861
+ const path = paths.get(node)
1862
+ if ((path.parent.type === 'CallExpression' || path.parent.type === 'OptionalCallExpression') && path.key === 'callee'
1863
+ || path.parent.type === 'TaggedTemplateExpression' && path.key === 'tag') {
1864
+ text = referenceCells.has(candidate) ? `${candidate}().callee` : `(0,${text})`
1865
+ }
1866
+ return mapped(text, node)
1867
+ }
1868
+ return original(node.start, node.end)
1869
+ }
1870
+ if (target === 'module' && node.type === 'ImportDeclaration') {
1871
+ const edits = node.specifiers.filter(specifier => importNames.has(specifier.local)).map(specifier => ({ start: specifier.local.start, end: specifier.local.end,
1872
+ text: `${specifier.type === 'ImportSpecifier' && specifier.imported.start === specifier.local.start
1873
+ ? `${code.slice(specifier.imported.start, specifier.imported.end)} as ` : ''}${importNames.get(specifier.local)}` }))
1874
+ let cursor = node.start
1875
+ const parts = []
1876
+ for (const edit of edits) { parts.push(original(cursor, edit.start), part(edit.text)); cursor = edit.end }
1877
+ parts.push(original(cursor, node.end))
1878
+ return join(parts)
1879
+ }
1880
+ if (target === 'module' && node.type === 'ExportNamedDeclaration' && !node.source) {
1881
+ return node.declaration ? emit(node.declaration, candidates) : part('')
1882
+ }
1883
+ if (target === 'module' && node.type === 'ExportDefaultDeclaration') {
1884
+ const { group, exported, native } = defaultExports.get(node)
1885
+ if (native) return join([original(node.start, node.declaration.start), emit(node.declaration, candidates)])
1886
+ return group ? emit(node.declaration,candidates)
1887
+ : join([part(`let ${exported.publicName}=(`),emitInitializer(node.declaration,candidates,'default'),part(');')])
1888
+ }
1889
+ if (target === 'module' && (node.type === 'ExportAllDeclaration'
1890
+ || node.type === 'ExportNamedDeclaration' && node.source)) return original(node.start,node.end)
1891
+ if (node.type === 'ObjectProperty' && node.shorthand) {
1892
+ return join([part(`[${JSON.stringify(node.key.name)}]: `), emit(node.value, candidates, suppress)])
1893
+ }
1894
+ if (node.type === 'AssignmentPattern') {
1895
+ return join([emit(node.left, candidates), part('=('), emitInitializer(node.right, candidates,
1896
+ occurrences.get(node.left)?.name ?? node.left.name), part(')')])
1897
+ }
1898
+ if (node.type === 'AssignmentExpression' && ['=', '&&=', '||=', '??='].includes(node.operator)) {
1899
+ let target = node.left
1900
+ while ((target.type.startsWith('TS') || target.type === 'ParenthesizedExpression') && target.expression) target = target.expression
1901
+ if (target.type === 'Identifier') return join([emit(node.left, candidates), part(`${node.operator}(`),
1902
+ emitInitializer(node.right, candidates, target.name), part(')')])
1903
+ }
1904
+ if (LOOP_HEADS.has(node.type)) {
1905
+ const head = node.type === 'ForStatement' ? node.init : node.left
1906
+ if (head?.type === 'VariableDeclaration' && declarationGroups.has(head)) {
1907
+ const headGroups = introductions.get(node) ?? []
1908
+ if (node.type === 'ForStatement') {
1909
+ const heads = headGroups.map(group => `${group.cell}=${factory}(${JSON.stringify(group.name)})`)
1910
+ const firstIteration=headGroups.length?allocate('local_first_iteration'):undefined
1911
+ const inputs = head.declarations.map(entry => {
1912
+ if (entry.init !== null) return declarator(entry, candidates, true)
1913
+ const ensures = bindingNodes(entry.id).map(binding => occurrences.get(binding).group)
1914
+ .map(group => `${group.cell}.ensure()`).join(',')
1915
+ return part(`${allocate('local_initialization')}=(${ensures})`)
1916
+ })
1917
+ return join([part(`for(let ${heads.length ? `${heads.join(',')},` : ''}`),
1918
+ ...inputs.flatMap((input, index) => index ? [part(','), input] : [input]),
1919
+ part(firstIteration?`,${firstIteration}=true;${firstIteration}&&(${firstIteration}=false,${headGroups.map(group=>`${group.cell}=${group.cell}.copy()`).join(',')}),`:';'),
1920
+ ...(node.test ? [emit(node.test, candidates)] : firstIteration?[part('true')]:[]), part(';'),
1921
+ part(headGroups.map(group => `${group.cell}=${group.cell}.copy()`).join(',')),
1922
+ ...(node.update ? [part(headGroups.length ? ',' : ''), emit(node.update, candidates)] : []),
1923
+ part(')'), emit(node.body, candidates)])
1924
+ }
1925
+ const iteration = allocate('local_iteration')
1926
+ const keyword = head.kind === 'using' || head.kind === 'await using' ? head.kind : 'let'
1927
+ const sourceInitialization = node.type === 'ForInStatement' && head.declarations[0].init !== null
1928
+ ? declarator(head.declarations[0], candidates) : undefined
1929
+ const sourceCandidates = new Map(candidates)
1930
+ const headCells = headGroups.map(group => {
1931
+ const physicalName = allocate('iteration_head')
1932
+ sourceCandidates.set(group, physicalName)
1933
+ dynamicBindings.push({ physicalName, name: group.name, kind: 'let', property: 'v',
1934
+ role: 'binding', scopeStart: node.start, scopeEnd: node.right.end })
1935
+ return `let ${physicalName}=${factory}(${JSON.stringify(group.name)},void 0,false,void 0,void 0,true);`
1936
+ }).join('')
1937
+ // The source sees a separate uninitialized head environment. Escaped
1938
+ // source closures retain it; each iteration creates its own live cells.
1939
+ const wrapped = headCells || sourceInitialization
1940
+ return join([part(wrapped ? `{${headCells}` : ''), ...(sourceInitialization ? [sourceInitialization] : []),
1941
+ part(`${loopLabels}for${node.await ? ' await' : ''}(${keyword} ${iteration} ${node.type === 'ForOfStatement' ? 'of' : 'in'} (`),
1942
+ emit(node.right, sourceCandidates), part(')){'), initializations(node, candidates),
1943
+ declarator(head.declarations[0], candidates, false, part(iteration)), emit(node.body, candidates),
1944
+ part(wrapped ? '}}' : '}')])
1945
+ }
1946
+ }
1947
+ if (node.type === 'VariableDeclaration' && declarationGroups.has(node) && !suppress.has(node)) {
1948
+ if (node.kind === 'using' || node.kind === 'await using') {
1949
+ return join(node.declarations.flatMap(entry => {
1950
+ const resource = allocate('local_resource')
1951
+ const group = occurrences.get(entry.id)?.group
1952
+ if (group?.nativeLexical && group.occurrences[0].node === entry.id) {
1953
+ return [part(`${node.kind} ${resource}=(`), emitInitializer(entry.init, candidates, occurrences.get(entry.id).name),
1954
+ part(`);let ${group.publicName}=${resource};${group.cell}.initialize(${resource});`)]
1955
+ }
1956
+ return mode === 'protected-v1'
1957
+ ? [part(`${node.kind} ${resource}=(`), emitInitializer(entry.init, candidates, occurrences.get(entry.id).name),
1958
+ part(`);${group.cell}.initialize(${resource});`)]
1959
+ : [part(`${node.kind} ${resource}=(`), emitInitializer(entry.init, candidates, occurrences.get(entry.id).name), part(');('),
1960
+ emitPattern(entry.id, candidates), part(`=${resource});`)]
1961
+ }))
1962
+ }
1963
+ const operations = join(node.declarations.map(entry => declarator(entry, candidates)))
1964
+ return guardedBodies.has(node)
1965
+ ? join([part('{'), operations, part('}')]) : operations
1966
+ }
1967
+ if ((node.type === 'FunctionDeclaration' || node.type === 'ClassDeclaration')
1968
+ && node.id && declarationGroups.has(node) && !suppress.has(node)) {
1969
+ const group = occurrences.get(node.id).group
1970
+ if (active.has(group)) {
1971
+ if (group.hoisted) {
1972
+ if (group.accessor) return node === group.hoistedDeclaration
1973
+ ? emit(node, candidates, new Set([node])) : part(';')
1974
+ const promoted = promotedFunctions.get(node)
1975
+ if (!promoted) return part(';')
1976
+ if (active.has(promoted)) return mapped(`${read(promoted, candidates)}=${read(group, candidates)};`, node)
1977
+ // Annex B publishes to the proven var owner, outside any with or
1978
+ // catch environment surrounding the block declaration's execution.
1979
+ let publication = rootPublications.get(promoted)
1980
+ if (!publication) {
1981
+ publication = allocate('annex_publication')
1982
+ rootPublications.set(promoted, publication)
1983
+ compilerLocalBindings.add(publication)
1984
+ }
1985
+ return mapped(`${publication}(${read(group, candidates)});`, node)
1986
+ }
1987
+ if (group.nativeLexical && node === group.occurrences[0].declaration) {
1988
+ return join([part(`let ${group.publicName}=(`), emit(node, candidates, new Set([node])),
1989
+ part(`);${group.cell}.initialize(${group.publicName});`)])
1990
+ }
1991
+ return join([part(mode === 'protected-v1' ? `${group.cell}.initialize(` : `${group.cell}.v=(`),
1992
+ emit(node, candidates, new Set([node])), part(');')])
1993
+ }
1994
+ }
1995
+ const discriminant = node.type === 'SwitchStatement' && introductions.has(node)
1996
+ ? allocate('switch_discriminant') : undefined
1997
+ if (discriminant) {
1998
+ compilerLocalBindings.add(discriminant)
1999
+ dynamicBindings.push({ physicalName: discriminant, role: 'source-initializer' })
2000
+ }
2001
+ const children = []
2002
+ for (const key of babelTypes.VISITOR_KEYS[node.type] ?? []) {
2003
+ const value = node[key]
2004
+ for (const child of Array.isArray(value) ? value : [value]) {
2005
+ if (child && typeof child === 'object' && typeof child.type === 'string'
2006
+ && Number.isInteger(child.start) && child.start >= node.start && child.end <= node.end) children.push(child)
2007
+ }
2008
+ }
2009
+ children.sort((a, b) => a.start - b.start || b.end - a.end)
2010
+ let cursor = node.start
2011
+ const parts = []
2012
+ const statementList = node.type === 'BlockStatement' || node.type === 'Program' ? new Set(node.body) : undefined
2013
+ const statements = []
2014
+ for (const child of children) {
2015
+ if (child.start < cursor) continue
2016
+ const privateKey = privateMembers.get(node)?.public && node.computed && child === node.key
2017
+ const gap = original(cursor, privateKey ? code.lastIndexOf('[', child.start) : child.start)
2018
+ const value = discriminant && child === node.discriminant ? mapped(discriminant, child) : emit(child, candidates, suppress)
2019
+ if (statementList?.has(child)) {
2020
+ if (statements.length === 0) parts.push(gap)
2021
+ else statements.push(gap)
2022
+ statements.push(value)
2023
+ } else parts.push(gap, value)
2024
+ cursor = privateKey ? code.indexOf(']', child.end) + 1 : child.end
2025
+ }
2026
+ if (statements.length) parts.push(statementPieces(statements, node))
2027
+ parts.push(original(cursor, node.end))
2028
+ let result = join(parts)
2029
+ const parent = paths.parentFor(node)
2030
+ const owner = introductions.has(node) ? node
2031
+ : node.type === 'BlockStatement' && (isFunctionNode(parent) || parent.type === 'CatchClause')
2032
+ && introductions.has(parent) ? parent : undefined
2033
+ if (owner && (node.type === 'BlockStatement' || node.type === 'StaticBlock')) {
2034
+ const prefix = join([...(owner === node && isFunctionNode(parent) ? [initializations(parent, candidates)] : []),
2035
+ initializations(owner, candidates)])
2036
+ const offset = node.directives?.length ? node.directives.at(-1).end-node.start
2037
+ : node.type === 'StaticBlock' ? code.indexOf('{', node.start) - node.start + 1 : 1
2038
+ // The opening token precedes every copied child, so inserting here cannot
2039
+ // split a transformed identifier or declaration.
2040
+ result = join([pieces.slice(result, 0, offset), prefix, pieces.slice(result, offset)])
2041
+ }
2042
+ if (discriminant) {
2043
+ // The physical case cells must also be outside the discriminant's
2044
+ // environment, including direct eval and closures that escape it.
2045
+ result = join([part(`{const ${discriminant}=(`), emit(node.discriminant, candidates),
2046
+ part(');{'), initializations(node, candidates), result, part('}}')])
2047
+ }
2048
+ if (node.type === 'ArrowFunctionExpression' && node.body.type !== 'BlockStatement' && introductions.has(node)) {
2049
+ const body = emit(node.body, candidates)
2050
+ const arrowEnd = callableMarkerPosition(node, code, tree.comments) + 2
2051
+ const head = []
2052
+ let headCursor = node.start
2053
+ for (const parameter of node.params) {
2054
+ head.push(original(headCursor, parameter.start), emit(parameter, candidates))
2055
+ headCursor = parameter.end
2056
+ }
2057
+ head.push(original(headCursor, arrowEnd))
2058
+ result = join([...head, part('{'), initializations(node, candidates), part('return ('), body, part(');}')])
2059
+ }
2060
+ return node.type === 'BlockStatement' && pieces.length(result) > 16384
2061
+ ? pieces.region(result, { kind: 'block', ...regionContext(node) }) : result
2062
+ }
2063
+ onPhase?.('emit')
2064
+ const transformed = emit(tree.program)
2065
+ onPhase?.('emitted')
2066
+ const adapter = decoratorContexts.size === 0 ? '' : `${target === 'module' ? '' : `const ${decoratorAdapter}=`}function ${decoratorAdapter}(decorator,receiver,name,isPrivate){return function(value,context){context.name=name;context.private=isPrivate;if(typeof value==="function")${intrinsics}.Object.defineProperty(value,"name",{value:(context.kind==="getter"?"get ":context.kind==="setter"?"set ":"")+name,configurable:true});if(!isPrivate){context.access={has:object=>name in object,...(context.kind==="setter"?{}:{get:object=>object[name]}),...(context.kind==="method"||context.kind==="getter"?{}:{set:(object,value)=>{object[name]=value}})}}return ${intrinsics}.Reflect.apply(decorator,receiver,[value,context])}}${target === 'module' ? '' : ';'}\n`
2067
+ const needsPrivateNames = [...privateClasses.values()].some(plan => [...plan.groups.values()]
2068
+ .some(group => [...group.targets.values()].some(owner => owner.nameReady)))
2069
+ const helper = intrinsicBootstrap(intrinsics, target, intrinsicContext) + adapter
2070
+ + (needsPrivateNames ? target === 'module' ? `var ${privateNames};\n` : `const ${privateNames}=${intrinsics}.weakSetStore();\n` : '')
2071
+ + (varReferenceMarker ? `const ${varReferenceMarker}=void 0;\n` : '')
2072
+ + (target === 'module' ? '' : `const ${factory}=`)
2073
+ + `function ${factory}(name,value,ready=false,get,set,lexical=false,readOnly=false){let target;return {get v(){if(target)return target.v;if(get)return get();if(!ready)throw new ${intrinsics}.ReferenceError("Cannot access '"+name+"' before initialization");return value},set v(next){if(lexical&&!ready)throw new ${intrinsics}.ReferenceError("Cannot access '"+name+"' before initialization");if(readOnly)throw new ${intrinsics}.TypeError("Assignment to constant variable.");this.initialize(next)},initialize(next){if(target){target.v=next;return}if(set){set(next);return}value=next;ready=true;get=void 0},ensure(){if(!ready&&!get)this.initialize(void 0)},commit(next){if(!ready)return;next.initialize(this.v);target=next},copy(){return ${factory}(name,this.v,true)}}}${target === 'module' ? '' : ';'}\n`
2074
+ const exports = moduleExports.size === 0 ? '' : `\nexport {${[...moduleExports].map(([name,group])=>`${group.accessor??group.publicName} as ${JSON.stringify(name)}`).join(',')}};`
2075
+ const directiveEnd=tree.program.directives.at(-1)?.end??0
2076
+ const body = pieces.slice(transformed, directiveEnd)
2077
+ const publications = [...rootPublications].map(([group, name]) => mapped(
2078
+ `function ${name}(value){${group.name}=value;}\n`, group.occurrences[0].node))
2079
+ const result = join([original(0,directiveEnd),part('\n'+helper), ...publications,
2080
+ initializations(tree.program,new Map()), body, part(exports)])
2081
+ const privateBindings = [...privateDeclarations].map(([node, declared]) => ({ scopeStart: node.start, scopeEnd: node.end,
2082
+ hiddenNames: [...declared].filter(name => typescript.internalPrivateNames?.has(name)),
2083
+ names: [...privateClasses.get(node)?.groups ?? []].filter(([name]) => !typescript.internalPrivateNames?.has(name)).map(([name, group]) => ({ name, bridgeExpression: privateBridge(group),
2084
+ targets: [...group.targets.values()].map(owner => ({ physicalName: owner.physical, static: owner.static, sourceStart: owner.last })) })) }))
2085
+ return finish({ outputPlan: { pieces, root: result, code, sourceMap,
2086
+ regionFacts: { allocate, decorated, resources, lexicalDynamic } },
2087
+ dynamicBindings, privateBindings,
2088
+ ...(protectedModule ? { moduleLexicalExports: new Set([...moduleExports].filter(([, group]) => active.has(group)).map(([name]) => name)) } : {}),
2089
+ internalBindings: new Set([factory, intrinsics, ...compilerLocalBindings, ...(decoratorContexts.size ? [decoratorAdapter] : []),
2090
+ ...(needsPrivateNames ? [privateNames] : [])]) })
2091
+ }