dsh-ptc-plus 0.3.1 → 0.4.1

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 (200) hide show
  1. package/README.en.md +66 -73
  2. package/README.md +66 -73
  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 +30610 -722
  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 +554 -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 +6 -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 +6 -4
  25. package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
  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 +9 -3
  31. package/docs/adr/0014-persist-cell-rewrite-policy.md +11 -5
  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 +8 -6
  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 +17 -3
  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 +82 -22
  48. package/docs/binding-review-placement-design.md +200 -0
  49. package/docs/capability-projection.md +1 -1
  50. package/docs/client-ui.md +96 -20
  51. package/docs/durability-design.md +61 -24
  52. package/docs/evaluation.md +78 -6
  53. package/docs/installation.md +41 -6
  54. package/docs/program-data-plane.md +6 -0
  55. package/docs/publishing.md +5 -3
  56. package/docs/runtime-reference.md +79 -25
  57. package/docs/semantic-validation.md +29 -0
  58. package/docs/stateful-binding-updates-proposal.md +755 -0
  59. package/docs/user-bindings.en.md +64 -0
  60. package/docs/user-bindings.md +64 -0
  61. package/docs/value-wire.md +3 -3
  62. package/docs/verification.md +57 -0
  63. package/index.js +374 -92
  64. package/internal/ast-traversal.js +5 -2
  65. package/internal/binding-descriptors.js +1 -0
  66. package/internal/binding-pattern-traversal.js +25 -0
  67. package/internal/binding-pattern.js +26 -29
  68. package/internal/binding-source-analysis.js +391 -0
  69. package/internal/binding-update-policy.js +66 -0
  70. package/internal/bounded-worker-round.js +56 -0
  71. package/internal/callable-definition-environment.js +42 -0
  72. package/internal/callable-source-catalog.js +129 -0
  73. package/internal/callable-source-encoding.js +47 -0
  74. package/internal/callable-source-facts.js +459 -0
  75. package/internal/callable-source-format.js +2 -0
  76. package/internal/callable-source-lowering.js +123 -0
  77. package/internal/cell-analysis-contract.js +25 -0
  78. package/internal/cell-analysis.js +252 -242
  79. package/internal/cell-completion.js +15 -0
  80. package/internal/cell-error.js +7 -0
  81. package/internal/cell-parser.js +66 -0
  82. package/internal/cell-rewriter.js +3 -553
  83. package/internal/commonjs-export-evidence.js +63 -0
  84. package/internal/commonjs-source-evidence.js +72 -0
  85. package/internal/compiler-amaro.cjs +2 -0
  86. package/internal/compiler-compression.js +12 -0
  87. package/internal/compiler-data.js +58 -0
  88. package/internal/compiler-descriptors.js +54 -0
  89. package/internal/compiler-dynamic-cache.js +48 -0
  90. package/internal/compiler-entry.js +35 -0
  91. package/internal/compiler-generated-names.js +17 -0
  92. package/internal/compiler-intrinsics.js +84 -0
  93. package/internal/compiler-module-links.js +34 -0
  94. package/internal/compiler-operations.js +61 -0
  95. package/internal/compiler-platform-factory.js +84 -0
  96. package/internal/compiler-platform.js +136 -0
  97. package/internal/compiler-record-roles.js +53 -0
  98. package/internal/compiler-region-output.js +259 -0
  99. package/internal/compiler-resource-lowering.js +103 -0
  100. package/internal/compiler-scope-facts.js +115 -0
  101. package/internal/compiler-service.js +109 -0
  102. package/internal/compiler-source-cache.js +32 -0
  103. package/internal/compiler-source-pieces.js +93 -0
  104. package/internal/compiler-source-regions.js +132 -0
  105. package/internal/compiler-storage-source.js +54 -0
  106. package/internal/compiler-text.js +15 -0
  107. package/internal/compiler-typescript.cjs +2 -0
  108. package/internal/config-spec.js +91 -25
  109. package/internal/cordis-tools-owner.js +130 -21
  110. package/internal/diagnostic.js +27 -1
  111. package/internal/direct-surface-owner.js +76 -23
  112. package/internal/dynamic-binding-evidence.js +16 -0
  113. package/internal/dynamic-environment-compiler.js +779 -0
  114. package/internal/dynamic-environment-integration.js +87 -0
  115. package/internal/dynamic-environment-runtime.js +362 -0
  116. package/internal/dynamic-native-calls.js +150 -0
  117. package/internal/dynamic-native-runtime.js +248 -0
  118. package/internal/dynamic-scope-analysis.js +90 -0
  119. package/internal/edit-transport-owner.js +28 -3
  120. package/internal/execution-seam-compat.js +193 -0
  121. package/internal/failure-reporting.js +118 -18
  122. package/internal/host-rpc.js +66 -0
  123. package/internal/isolated-worker.js +548 -0
  124. package/internal/kernel-child.js +139 -0
  125. package/internal/kernel-worker.js +911 -116
  126. package/internal/language-semantics.js +14 -0
  127. package/internal/legacy-binding-catalog.js +48 -0
  128. package/internal/legacy-cell-analysis.js +600 -0
  129. package/internal/legacy-cell-parser.js +50 -0
  130. package/internal/legacy-cell-rewriter.js +631 -0
  131. package/internal/legacy-repl-convenience.js +291 -0
  132. package/internal/managed-module-operations.js +170 -0
  133. package/internal/module-compilation.js +321 -0
  134. package/internal/module-runtime-platform.js +19 -0
  135. package/internal/module-transform-contract.js +12 -0
  136. package/internal/native-await-declarations.js +68 -0
  137. package/internal/native-root-compilation.js +54 -0
  138. package/internal/native-root-dynamic.js +67 -0
  139. package/internal/recovery-tips.js +27 -15
  140. package/internal/rejected-cell-editor.js +13 -8
  141. package/internal/repl-convenience.js +2 -201
  142. package/internal/repl-memory-projection.js +81 -12
  143. package/internal/repl-observation-interest.js +70 -0
  144. package/internal/repl-rewrite-contract.js +21 -0
  145. package/internal/repl-scope-normalizer.js +2091 -0
  146. package/internal/repl-value-observer.js +114 -0
  147. package/internal/rpc-contract.js +52 -0
  148. package/internal/runtime-bridge-owner.js +172 -28
  149. package/internal/runtime-config.js +48 -51
  150. package/internal/runtime-contexts.js +82 -10
  151. package/internal/runtime-messages.js +111 -0
  152. package/internal/session-cell-executor.js +455 -91
  153. package/internal/session-journal-recovery.js +684 -0
  154. package/internal/session-journal-schema.js +106 -0
  155. package/internal/session-journal.js +237 -440
  156. package/internal/session-log-view.js +42 -9
  157. package/internal/session-runtime.js +325 -80
  158. package/internal/session-state.js +249 -40
  159. package/internal/source-position-map.js +211 -71
  160. package/internal/stateful-module-compiler.js +154 -0
  161. package/internal/stateful-module-runtime.js +303 -0
  162. package/internal/stateful-root-compiler.js +598 -0
  163. package/internal/stateful-root-runtime.js +340 -0
  164. package/internal/typert-codec-compat.js +28 -0
  165. package/internal/typescript-transform.js +29 -0
  166. package/internal/user-binding-authoring.js +70 -0
  167. package/internal/user-binding-console-worker.js +184 -0
  168. package/internal/user-binding-console.js +148 -0
  169. package/internal/user-binding-draft-projection.js +335 -0
  170. package/internal/user-binding-model-context.js +31 -0
  171. package/internal/user-binding-runner.js +56 -0
  172. package/internal/user-bindings-owner.js +1065 -0
  173. package/internal/user-bindings-store.js +293 -0
  174. package/internal/user-bindings.js +353 -0
  175. package/internal/value-wire-schema.js +28 -0
  176. package/internal/value-wire.js +29 -20
  177. package/internal/worker-client.js +57 -67
  178. package/internal/worker-environment.js +45 -0
  179. package/internal/worker-output-relay.js +29 -0
  180. package/internal/worker-shutdown.js +14 -0
  181. package/package.json +81 -11
  182. package/src/client-activity.js +109 -45
  183. package/src/client-authoring-view.js +580 -0
  184. package/src/client-binding-review.js +230 -0
  185. package/src/client-bindings-data.js +29 -0
  186. package/src/client-catalog.js +127 -0
  187. package/src/client-code-editor.js +84 -0
  188. package/src/client-console.js +112 -0
  189. package/src/client-copy.js +370 -0
  190. package/src/client-feature-gates.js +62 -0
  191. package/src/client-host-compat.js +150 -0
  192. package/src/client-indicator-view.js +267 -0
  193. package/src/client-repl-view.js +292 -0
  194. package/src/client-rpc.js +20 -0
  195. package/src/client-settings-view.js +221 -0
  196. package/src/client-styles.js +106 -0
  197. package/src/client-tool-view.js +108 -0
  198. package/src/client-transport.js +159 -0
  199. package/src/client-workbench.js +521 -0
  200. package/src/client.js +233 -615
@@ -0,0 +1,779 @@
1
+ import { parse, parseExpression } from '@babel/parser'
2
+ import traverseModule from '@babel/traverse'
3
+ import { transformFromAstSync, types as t } from '@babel/core'
4
+ import generatorImport from '@babel/generator'
5
+ import { createGeneratedNameAllocator, isWriteIdentifier as isWrite } from './binding-pattern.js'
6
+ import { rewriteNativeCalls } from './dynamic-native-calls.js'
7
+ import { markCallableSources, collectCallableSources, regionCallableRanges } from './callable-source-facts.js'
8
+ import { identitySourceMap, mapSourceSpan, sourceLineStarts, sourceTextAtSpan } from './source-position-map.js'
9
+ import { transformRegionSource } from './compiler-region-output.js'
10
+ import { rewriteNativeAwaitDeclarations } from './native-await-declarations.js'
11
+ import { createDynamicScopeAnalysis, sourceBinding, sourceScopePath, sourceInParameters, sourceBindingVisible } from './dynamic-scope-analysis.js'
12
+ import { bindingNodes } from './binding-pattern.js'
13
+ import { visitSource } from './compiler-source-regions.js'
14
+ import { createCompilerOperationPlanner } from './compiler-operations.js'
15
+
16
+ const traverse = traverseModule.default ?? traverseModule
17
+ const generate = generatorImport.default ?? generatorImport
18
+ const member = (object, name) => t.memberExpression(t.cloneNode(object), t.identifier(name))
19
+ const call = (object, name, args = []) => t.callExpression(member(object, name), args)
20
+ const undefinedValue = () => t.unaryExpression('void', t.numericLiteral(0))
21
+ const namedValue = (name, value) => {
22
+ if (!t.isArrowFunctionExpression(value) && !((t.isFunctionExpression(value) || t.isClassExpression(value)) && value.id === null)) return value
23
+ const key = typeof name === 'string' ? t.stringLiteral(name) : name
24
+ const object = t.inherits(t.objectExpression([t.objectProperty(t.cloneNode(key), value, true)]), value)
25
+ return t.inherits(t.memberExpression(object, t.cloneNode(key), true), value)
26
+ }
27
+ const replaceIterationDeclaration = (path, target, initializers, allocate, nativeAwait = false) => {
28
+ if (initializers.length === 0) return path.replaceWith(target)
29
+ const loop = path.parentPath.node
30
+ if (nativeAwait) {
31
+ // The REPL await lowerer rejects initialized for-in headers. Its explicit
32
+ // cell result remains separate from declaration initialization effects.
33
+ loop.right = t.inherits(t.sequenceExpression([...initializers, loop.right]), loop.right)
34
+ return path.replaceWith(target)
35
+ }
36
+ // Retain the native initialized for-in form: its completion differs from an
37
+ // assignment-target loop. Private declarations contribute no body completion.
38
+ const iteration = t.identifier(allocate('initialized_iteration'))
39
+ path.replaceWith(t.variableDeclaration('var', [t.variableDeclarator(iteration,
40
+ t.sequenceExpression([...initializers, undefinedValue()]))]))
41
+ loop.body = t.blockStatement([
42
+ t.variableDeclaration('let', [t.variableDeclarator(t.identifier(allocate('iteration_write')),
43
+ t.assignmentExpression('=', target, t.cloneNode(iteration)))]), loop.body,
44
+ ])
45
+ }
46
+ const strictAt = path => path.isInStrictMode()
47
+ || path.isFunction() && path.node.body.directives?.some(directive => directive.value.value === 'use strict') === true
48
+ const lexicalOwner = path => path.findParent(parent =>
49
+ parent.isFunction() && !parent.isArrowFunctionExpression()
50
+ && (parent.get('body').isAncestor(path) || parent.node.params.some(parameter => parameter.start <= path.node.start && parameter.end >= path.node.end))
51
+ || parent.isStaticBlock()
52
+ || (parent.isClassProperty() || parent.isClassPrivateProperty() || parent.isClassAccessorProperty())
53
+ && parent.node.value !== null && (parent.node.value === path.node || parent.get('value').isAncestor(path)))
54
+
55
+ function compileStaticRegions(source, cell, parserOptions) {
56
+ const environment = cell.environmentExpression === undefined ? t.identifier(cell.environmentName) : parseExpression(cell.environmentExpression)
57
+ const sourceStarts = sourceLineStarts(source)
58
+ const planOperations = createCompilerOperationPlanner(cell)
59
+ const result = transformRegionSource({ code: source, sourceMap: identitySourceMap(source.length), sourceRegions: cell.sourceRegions }, parserOptions, input => {
60
+ const operations = planOperations(input.tree)
61
+ const allocate = cell.sourceRegions?.allocate ?? createGeneratedNameAllocator(input.tree)
62
+ const envelope = input.prefix ? input.tree.program.body[0] : undefined
63
+ const invocations = new WeakMap()
64
+ const originalCallees = new WeakSet()
65
+ const coordinates = { generatedStarts: sourceLineStarts(input.code), originalStarts: sourceStarts }
66
+ const absoluteNode = node => {
67
+ const span = mapSourceSpan({ line: node.loc.start.line, column: node.loc.start.column + 1,
68
+ end: { line: node.loc.end.line, column: node.loc.end.column + 1 } }, input.code, source, input.sourceMap, coordinates)
69
+ return { ...node, loc: { start: { line: span.line, column: span.column - 1 }, end: { line: span.end.line, column: span.end.column - 1 } } }
70
+ }
71
+ traverse(input.tree, {
72
+ Scopable(path) {
73
+ // A partition cannot prove that a binding is unchanged in other source
74
+ // regions. Babel must retain receivers across every potentially mutating
75
+ // getter/call; global source allocation owns all new temporary names.
76
+ for (const binding of Object.values(path.scope.bindings)) binding.constant = false
77
+ },
78
+ 'CallExpression|OptionalCallExpression|NewExpression|TaggedTemplateExpression|Decorator'(path) {
79
+ if (path.isCallExpression() || path.isOptionalCallExpression()) originalCallees.add(path.node.callee)
80
+ if (operations.owns(path.node)) return
81
+ const expression = path.node.callee ?? path.node.tag ?? path.node.expression
82
+ // Literal callables cannot produce the non-callable diagnostic. Keep
83
+ // invocation adaptation without retaining their overlapping bodies.
84
+ if (t.isFunctionExpression(expression) || t.isArrowFunctionExpression(expression)) return
85
+ const callee = absoluteNode(expression)
86
+ invocations.set(path.node, cell.calleeSource?.(callee) ?? sourceTextAtSpan(source, {
87
+ line: callee.loc.start.line, column: callee.loc.start.column + 1,
88
+ end: { line: callee.loc.end.line, column: callee.loc.end.column + 1 },
89
+ }, sourceStarts))
90
+ },
91
+ })
92
+ rewriteNativeCalls(input.tree, environment, {
93
+ operations, allocate,
94
+ originalCallees,
95
+ origin: node => ({ target: node.loc === undefined ? undefined : cell.evalOrigin?.(absoluteNode(node)), callee: invocations.get(node) }),
96
+ skip: operations.declaration,
97
+ })
98
+ if (envelope !== undefined) {
99
+ // Babel hoists optional-chain temporaries to the analysis envelope.
100
+ // Publish those private declarations in the real output body, retaining
101
+ // its directive prologue and native variable owner.
102
+ const declarations = [...input.tree.program.body, ...envelope.body.body]
103
+ .filter(node => t.isVariableDeclaration(node) && node.loc === undefined)
104
+ const body = input.region.kind === 'block' ? input.selected.body[0].body : input.selected.body
105
+ let insertion = 0
106
+ while (t.isExpressionStatement(body[insertion]) && t.isStringLiteral(body[insertion].expression)) insertion++
107
+ body.splice(insertion, 0, ...declarations)
108
+ }
109
+ const generated = generate(t.program(input.selected.body, input.selected.directives, input.tree.program.sourceType),
110
+ { sourceMaps: true, sourceFileName: 'ptc-region.ts', compact: cell.compactOutput === true }, input.code)
111
+ generated.callableRanges = regionCallableRanges(input, generated, cell.callableRanges, parserOptions)
112
+ return generated
113
+ }, cell.callableCollector?.collect)
114
+ return { code: result.code, sourceOffsets: result.sourceMap, sourceRegions: result.sourceRegions,
115
+ callableRanges: cell.callableCollector === undefined ? result.callableRanges
116
+ : [...cell.callableCollector.resolve(result.callableRanges).values()], environmentName: cell.environmentName, varNames: [] }
117
+ }
118
+
119
+ /** Compile standard eval syntax against an explicit calling environment. */
120
+ export function compileDynamicEnvironmentSource(source, { strict = false, allowNewTarget = false, cell,
121
+ privateNames = [], allowSuper = false, allowSuperCall = false, forbidArguments = false, functionConstructor = false, resolveOriginalSource } = {}) {
122
+ const commonJs = cell?.sourceType === 'commonjs'
123
+ const parserOptions = { sourceType: cell?.sourceType ?? 'script', strictMode: strict || cell?.sourceType === 'module',
124
+ ...(commonJs ? {} : { allowNewTargetOutsideFunction: allowNewTarget }), allowSuperOutsideMethod: allowSuper,
125
+ errorRecovery: privateNames.length > 0,
126
+ ...(cell === undefined ? {} : { ...(commonJs ? {} : { allowAwaitOutsideFunction: true, allowReturnOutsideFunction: true }),
127
+ plugins: cell.parserPlugins }) }
128
+ if (cell?.staticOnly === true) return compileStaticRegions(source, cell, parserOptions)
129
+ const originalSource = source
130
+ const originalLineStarts = sourceLineStarts(originalSource)
131
+ const marked = cell === undefined ? markCallableSources(source, undefined, parserOptions, { resolveOriginalSource }) : undefined
132
+ if (marked !== undefined) source = marked.code
133
+ const tree = parse(source, parserOptions)
134
+ const operations = createCompilerOperationPlanner(cell)(tree)
135
+ const dynamicScopeAnalysis = createDynamicScopeAnalysis(tree)
136
+ // Capture references before lexical resolution or value exposure replaces them.
137
+ const invocationSources = new WeakMap()
138
+ visitSource(tree, { 'CallExpression|OptionalCallExpression|NewExpression|TaggedTemplateExpression|Decorator'(path) {
139
+ if (operations.owns(path.node)) return
140
+ const callee = path.node.callee ?? path.node.tag ?? path.node.expression
141
+ if (t.isFunctionExpression(callee) || t.isArrowFunctionExpression(callee)) return
142
+ const span = { line: callee.loc.start.line, column: callee.loc.start.column + 1,
143
+ end: { line: callee.loc.end.line, column: callee.loc.end.column + 1 } }
144
+ invocationSources.set(path.node, cell?.calleeSource?.(callee)
145
+ ?? sourceTextAtSpan(originalSource, marked === undefined ? span : mapSourceSpan(span, source, originalSource, marked.sourceMap), originalLineStarts))
146
+ } })
147
+ const callOrigin = node => ({
148
+ target: node.loc === undefined ? undefined : cell?.evalOrigin?.(node),
149
+ callee: invocationSources.get(node),
150
+ })
151
+ if (functionConstructor) {
152
+ const fn = tree.program.body[0].expression
153
+ fn.id = null
154
+ tree.program.body[0].expression = namedValue('anonymous', fn)
155
+ }
156
+ const externalPrivate = new Set()
157
+ for (const error of tree.errors) {
158
+ if (error.reasonCode !== 'InvalidPrivateFieldResolution' || !privateNames.includes(error.details.identifierName)) throw error
159
+ externalPrivate.add(error.pos)
160
+ }
161
+ const { sourceInitializers, declaration: internalDeclaration } = operations
162
+ // Babel models the block lexical declaration but deliberately omits Annex B's
163
+ // additional var binding. Expose that native binding before resolving names.
164
+ const annexFunctions = new WeakSet()
165
+ const annexVars = new Map()
166
+ traverse(tree, {
167
+ FunctionDeclaration(path) {
168
+ if (cell !== undefined || strict || strictAt(path) || path.node.async || path.node.generator) return
169
+ if (path.parentPath.isProgram() || path.parentPath.isBlockStatement() && path.parentPath.parentPath.isFunction()) return
170
+ if (!path.parentPath.isBlockStatement() && !path.parentPath.isSwitchCase()) {
171
+ path.replaceWith(t.blockStatement([path.node]))
172
+ return
173
+ }
174
+ const owner = path.getFunctionParent()?.scope ?? path.findParent(parent => parent.isProgram()).scope
175
+ let current = path.scope.parent
176
+ while (current !== null) {
177
+ const binding = current.getOwnBinding(path.node.id.name)
178
+ if (binding !== undefined && binding.path.node !== path.node && !['var', 'param', 'hoisted'].includes(binding.kind)) return
179
+ if (current === owner) break
180
+ current = current.parent
181
+ }
182
+ const names = annexVars.get(owner) ?? new Set()
183
+ names.add(path.node.id.name)
184
+ annexVars.set(owner, names)
185
+ if (owner.path.isProgram()) annexFunctions.add(path.node)
186
+ },
187
+ })
188
+ for (const [scope, names] of annexVars) {
189
+ const body = scope.path.isProgram() ? scope.path.node : scope.path.node.body
190
+ body.body.unshift(t.variableDeclaration('var', [...names].map(name => t.variableDeclarator(t.identifier(name)))))
191
+ }
192
+ traverse(tree, { Program(path) { path.scope.crawl(); path.stop() } })
193
+ const allocate = createGeneratedNameAllocator(tree)
194
+ const environmentName = cell?.environmentName ?? allocate('eval_environment')
195
+ const incoming = cell?.environmentExpression === undefined ? t.identifier(environmentName) : parseExpression(cell.environmentExpression)
196
+ const logicalBindings = new Map((cell?.bindings ?? []).map(binding => [binding.physicalName, binding]))
197
+ const candidateRegions = new Map()
198
+ // Candidate identifiers are proven by the normalizer. Their assignment owns
199
+ // the pattern and initializer, independently of later source-map insertions.
200
+ // A containing native scope can outlive that region, as in a for initializer.
201
+ const candidateTargets = (node, region) => {
202
+ if (t.isMemberExpression(node)) {
203
+ const receiver = t.isMemberExpression(node.object) && t.isIdentifier(node.object.object)
204
+ && logicalBindings.get(node.object.object.name)?.property === node.object.property.name
205
+ ? node.object.object : node.object
206
+ const physical = t.isCallExpression(receiver) ? receiver.callee : receiver
207
+ const binding = t.isIdentifier(physical) ? logicalBindings.get(physical.name) : undefined
208
+ if (binding?.role === 'candidate') {
209
+ const regions = candidateRegions.get(binding.physicalName) ?? []
210
+ regions.push(region)
211
+ candidateRegions.set(binding.physicalName, regions)
212
+ }
213
+ } else if (t.isArrayPattern(node)) {
214
+ for (const element of node.elements) candidateTargets(element, region)
215
+ } else if (t.isObjectPattern(node)) {
216
+ for (const property of node.properties) candidateTargets(t.isRestElement(property) ? property.argument : property.value, region)
217
+ } else if (t.isAssignmentPattern(node)) candidateTargets(node.left, region)
218
+ else if (t.isRestElement(node)) candidateTargets(node.argument, region)
219
+ }
220
+ traverse(tree, { AssignmentExpression(path) { candidateTargets(path.node.left, path.node) } })
221
+ const hiddenBindings = new Set([environmentName, cell?.rootRuntime, ...cell?.internalBindings ?? []].filter(name => name !== undefined))
222
+ const states = new WeakMap()
223
+ const generated = new WeakSet()
224
+ const nativePlaceholders = new WeakSet()
225
+ const functionPlans = []
226
+ const functionScopes = new Map()
227
+ const creationPlans = []
228
+ const withPlans = []
229
+ const varNames = new Set()
230
+ const varDeclarations = []
231
+ const functions = []
232
+ const annexPublications = []
233
+ let programPath
234
+ let programState
235
+ const withSensitive = path => {
236
+ let child = path
237
+ for (let parent = path.parentPath; parent !== null; child = parent, parent = parent.parentPath) {
238
+ if (parent.isFunction()) return false
239
+ if (parent.isWithStatement() && child.key === 'body') return true
240
+ }
241
+ return false
242
+ }
243
+ const mark = node => { generated.add(node); return node }
244
+ const replace = (path, node) => path.replaceWith(mark(t.inherits(node, path.node)))
245
+ const stateFor = path => {
246
+ for (let current = path; current !== null; current = current.parentPath) {
247
+ const state = states.get(current.node)
248
+ if (state !== undefined) return state
249
+ }
250
+ }
251
+ const inferredCallableKey = path => {
252
+ const owner = path.parentPath
253
+ if (owner.isObjectProperty()) {
254
+ if (owner.node.computed) {
255
+ const key = t.identifier(allocate('callable_key'))
256
+ hiddenBindings.add(key.name)
257
+ let scope = owner.scope
258
+ while (scope.path.isFunction() && sourceInParameters(path, scope)) scope = scope.parent
259
+ scope.push({ id: t.cloneNode(key), kind: 'let' })
260
+ owner.node.key = t.assignmentExpression('=', t.cloneNode(key),
261
+ call(incoming, 'propertyKey', [owner.node.key]))
262
+ return key
263
+ }
264
+ const name = owner.node.key.name ?? String(owner.node.key.value)
265
+ return name === '__proto__' ? undefined : t.stringLiteral(name)
266
+ }
267
+ const target = owner.isVariableDeclarator() ? owner.node.id
268
+ : owner.isAssignmentPattern() || owner.isAssignmentExpression() ? owner.node.left : undefined
269
+ return t.isIdentifier(target) ? t.stringLiteral(target.name) : undefined
270
+ }
271
+ const isSelfBinding = binding => binding?.kind === 'local' && binding.scope.path.isFunctionExpression()
272
+ && binding.identifier === binding.scope.path.node.id
273
+ // Babel combines a named expression's self and same-name body declarations
274
+ // under kind local. Recover native declaration ownership before lowering.
275
+ const bodyKinds = new WeakMap()
276
+ const bodyBindingKind = binding => {
277
+ if (!isSelfBinding(binding)) return undefined
278
+ if (!bodyKinds.has(binding)) {
279
+ const declaration = binding.constantViolations.find(path =>
280
+ (path.isVariableDeclarator() || path.isClassDeclaration() || path.isFunctionDeclaration())
281
+ && path.getFunctionParent()?.scope === binding.scope
282
+ && bindingNodes(path.node.id).some(node => node.name === binding.identifier.name))
283
+ bodyKinds.set(binding, declaration?.isVariableDeclarator() ? declaration.parent.kind
284
+ : declaration?.isClassDeclaration() ? 'let' : declaration?.isFunctionDeclaration() ? 'hoisted' : undefined)
285
+ }
286
+ return bodyKinds.get(binding)
287
+ }
288
+ const descriptorMap = (scope, extraArguments = false, exclude = new Set(), strictBindings = strictAt(scope.path), parametersOnly = false, origin = scope.path) => {
289
+ const entries = Object.entries(scope.bindings).filter(([name]) => !exclude.has(name) && !hiddenBindings.has(name))
290
+ .filter(([, binding]) => sourceBindingVisible(origin, binding))
291
+ .filter(([, binding]) => !isSelfBinding(binding) || bodyBindingKind(binding) !== undefined)
292
+ .filter(([, binding]) => !parametersOnly || binding.kind === 'param')
293
+ .map(([name, binding]) => ({ physicalName: name, name, kind: bodyBindingKind(binding) ?? binding.kind, ...logicalBindings.get(name) }))
294
+ .flatMap(binding => binding.names === undefined ? [binding] : binding.names.map(name => ({ ...binding, name })))
295
+ .filter(binding => binding.role !== 'candidate' || candidateRegions.get(binding.physicalName)?.some(region =>
296
+ origin.node.start >= region.start && origin.node.end <= region.end))
297
+ if (extraArguments && !entries.some(binding => binding.name === 'arguments')) {
298
+ entries.push({ physicalName: 'arguments', name: 'arguments', kind: 'param' })
299
+ }
300
+ return t.arrayExpression(entries.map(({ name, physicalName, property, kind, accessor, reference: delegated, referenceMethod }) => {
301
+ const physical = accessor === true ? t.callExpression(t.identifier(physicalName), []) : t.identifier(physicalName)
302
+ if (delegated === true || referenceMethod !== undefined) return t.arrayExpression([t.stringLiteral(name), t.objectExpression([
303
+ t.objectProperty(t.identifier('kind'), t.stringLiteral(kind)),
304
+ t.objectProperty(t.identifier('reference'), t.arrowFunctionExpression([], referenceMethod === undefined ? physical
305
+ : call(physical, referenceMethod, [t.stringLiteral(name), t.booleanLiteral(strictBindings)]))),
306
+ ])])
307
+ const value = t.identifier(allocate('eval_write'))
308
+ const target = property === undefined ? physical : member(physical, property)
309
+ return t.arrayExpression([t.stringLiteral(name), t.objectExpression([
310
+ t.objectProperty(t.identifier('kind'), t.stringLiteral(kind)),
311
+ t.objectProperty(t.identifier('get'), t.arrowFunctionExpression([], t.cloneNode(target))),
312
+ ...(name === 'arguments' && strictBindings ? [] : [
313
+ t.objectProperty(t.identifier('set'), t.arrowFunctionExpression([value],
314
+ t.assignmentExpression('=', t.cloneNode(target), t.cloneNode(value)))),
315
+ ]),
316
+ ])])
317
+ }))
318
+ }
319
+ const capture = (path, state, origin = path) => {
320
+ const scopes = []
321
+ let rootIndex = -1
322
+ let base = state.id
323
+ for (const scope of sourceScopePath(path, origin)) {
324
+ if (scope === state.boundary) break
325
+ const plan = functionScopes.get(scope)
326
+ if (plan?.parameters && sourceInParameters(origin, scope)) {
327
+ base = parameterEnvironment(plan)
328
+ break
329
+ }
330
+ if (cell?.nativeAwait === true && scope === programPath.scope) rootIndex = scopes.length
331
+ scopes.push(descriptorMap(scope, false, new Set(), strictAt(scope.path), false, origin))
332
+ }
333
+ return scopes.length === 0 ? t.cloneNode(base)
334
+ : call(base, 'capture', [t.arrayExpression(scopes), t.booleanLiteral(state.strict || strictAt(path)),
335
+ ...(rootIndex < 0 ? [] : [t.numericLiteral(rootIndex)])])
336
+ }
337
+ const selfBindingsFor = (plan, parameters = false) => plan.selfName === undefined
338
+ || (parameters ? plan.scope.getOwnBinding(plan.selfName)?.kind === 'param'
339
+ : !isSelfBinding(plan.scope.getOwnBinding(plan.selfName)) || bodyBindingKind(plan.scope.getOwnBinding(plan.selfName)) !== undefined) ? undefined : t.arrayExpression([t.arrayExpression([
340
+ t.stringLiteral(plan.selfName), t.objectExpression([
341
+ t.objectProperty(t.identifier('kind'), t.stringLiteral('self')),
342
+ t.objectProperty(t.identifier('get'), t.arrowFunctionExpression([], t.identifier(plan.selfName))),
343
+ ]),
344
+ ])])
345
+ const parameterEnvironment = plan => call(capture(plan.path.parentPath, plan.parent, plan.path), 'parameters', [
346
+ plan.parameterKey ?? t.identifier('arguments'), descriptorMap(plan.scope, false, new Set(), plan.state.strict, true),
347
+ plan.arrow ? undefinedValue() : t.arrowFunctionExpression([], t.thisExpression()),
348
+ plan.arrow ? undefinedValue() : t.arrowFunctionExpression([], t.metaProperty(t.identifier('new'), t.identifier('target'))),
349
+ t.booleanLiteral(plan.state.strict), t.booleanLiteral(!plan.arrow),
350
+ ...(selfBindingsFor(plan, true) === undefined ? [] : [selfBindingsFor(plan, true)]),
351
+ ])
352
+ const outerParameterPlan = path => {
353
+ for (let current = path.parentPath; current !== null; current = current.parentPath) if (current.isFunction()) {
354
+ if (!sourceInParameters(path, current.scope)) return undefined
355
+ const plan = functionScopes.get(current.scope)
356
+ if (plan?.parameters) return plan
357
+ }
358
+ return undefined
359
+ }
360
+ const captureCreation = path => {
361
+ const outer = outerParameterPlan(path)
362
+ if (outer === undefined) return undefined
363
+ const parent = stateFor(path.parentPath)
364
+ if (parent.creation === true) return parent
365
+ const state = { id: t.identifier(allocate('parameter_closure')), boundary: outer.scope,
366
+ strict: parent.strict, creation: true }
367
+ creationPlans.push({ path, parent, state })
368
+ hiddenBindings.add(state.id.name)
369
+ return state
370
+ }
371
+ const declarationMarker = node => t.isCallExpression(node) && t.isIdentifier(node.callee)
372
+ && logicalBindings.get(node.callee.name)?.role === 'var-reference'
373
+ traverse(tree, {
374
+ enter(path) {
375
+ if (declarationMarker(path.node)) mark(path.node)
376
+ if (path.isVariableDeclarator()) {
377
+ const initializer = logicalBindings.get(path.node.id.name)
378
+ if (initializer?.role === 'parameter-initializer') {
379
+ functionScopes.get(path.getFunctionParent().scope).parameterInitializers.push({ node: path.node, name: initializer.name })
380
+ }
381
+ }
382
+ if (internalDeclaration(path) || generated.has(path.node)) path.skip()
383
+ },
384
+ Program(path) {
385
+ programPath = path
386
+ const actualStrict = strict || path.node.sourceType === 'module' || path.node.directives.some(directive => directive.value.value === 'use strict')
387
+ if (cell === undefined && !actualStrict) for (const [name, binding] of Object.entries(path.scope.bindings)) {
388
+ if (binding.kind === 'var' || binding.kind === 'hoisted') varNames.add(name)
389
+ }
390
+ const id = cell === undefined ? t.identifier(allocate('eval_scope')) : incoming
391
+ programState = { id, boundary: cell?.module === true || cell?.nativeRoot === true ? null : path.scope, strict: actualStrict }
392
+ states.set(path.node, programState)
393
+ },
394
+ Function(path) {
395
+ const owner = path.parentPath
396
+ const physicalName = path.node.id?.name ?? (owner.isVariableDeclarator() ? owner.node.id.name : undefined)
397
+ if (physicalName !== undefined && (hiddenBindings.has(physicalName) && !sourceInitializers.has(physicalName)
398
+ || logicalBindings.get(physicalName)?.accessor === true)) {
399
+ mark(path.node)
400
+ path.skip()
401
+ return
402
+ }
403
+ if (path.isFunctionDeclaration() && varNames.has(path.node.id.name) && path.parentPath.isProgram()) {
404
+ functions.push(path)
405
+ }
406
+ if (annexFunctions.has(path.node)) annexPublications.push(path)
407
+ const parent = path.isFunctionExpression() || path.isArrowFunctionExpression()
408
+ ? captureCreation(path) ?? stateFor(path.parentPath) : stateFor(path.parentPath)
409
+ const id = t.identifier(allocate('eval_activation'))
410
+ const selfName = path.isFunctionExpression() && path.node.id !== null ? path.node.id.name : undefined
411
+ const state = { id, boundary: path.scope, strict: parent.strict || strictAt(path), selfName }
412
+ states.set(path.node.body, state)
413
+ const plan = { path, parent, state, scope: path.scope, node: path.node, arrow: path.isArrowFunctionExpression(), selfName,
414
+ parameterInitializers: [],
415
+ parameters: path.node.params.some(parameter => dynamicScopeAnalysis.containsDirectEval(parameter)) }
416
+ if (plan.parameters && plan.arrow) {
417
+ plan.parameterKey = t.identifier(allocate('parameter_key'))
418
+ hiddenBindings.add(plan.parameterKey.name)
419
+ path.node.params.unshift(plan.parameterKey)
420
+ plan.inferredKey = inferredCallableKey(path)
421
+ }
422
+ if (plan.parameters && path.scope.getOwnBinding('arguments')?.kind === 'param') {
423
+ const physicalName = allocate('parameter_arguments')
424
+ path.scope.rename('arguments', physicalName)
425
+ logicalBindings.set(physicalName, { physicalName, name: 'arguments', kind: 'param' })
426
+ }
427
+ functionPlans.push(plan)
428
+ functionScopes.set(path.scope, plan)
429
+ },
430
+ 'ObjectExpression|ClassExpression'(path) {
431
+ const state = captureCreation(path)
432
+ if (state !== undefined) states.set(path.node, state)
433
+ },
434
+ WithStatement(path) {
435
+ const parent = stateFor(path.parentPath)
436
+ const id = t.identifier(allocate('with_environment'))
437
+ const state = { id, boundary: path.scope, strict: false }
438
+ states.set(path.node.body, state)
439
+ withPlans.push({ path, parent, state })
440
+ },
441
+ VariableDeclaration(path) {
442
+ if (path.node.kind !== 'var') return
443
+ if (cell === undefined && path.getFunctionParent() === null && !programState.strict
444
+ || withSensitive(path)) varDeclarations.push(path)
445
+ },
446
+ AssignmentExpression(path) {
447
+ if (['=', '&&=', '||=', '??='].includes(path.node.operator) && t.isIdentifier(path.node.left)) {
448
+ path.node.right = namedValue(path.node.left.name, path.node.right)
449
+ }
450
+ },
451
+ AssignmentPattern(path) {
452
+ if (t.isIdentifier(path.node.left)) path.node.right = namedValue(path.node.left.name, path.node.right)
453
+ },
454
+ })
455
+ // Adapting an initializer does not remove its native variable declaration.
456
+ // Keep hoisted storage for function/strict/cell owners; sloppy eval roots
457
+ // instead publish these names through the incoming environment's varFrame.
458
+ const nativeVars = new Map()
459
+ for (const path of varDeclarations) {
460
+ const owner = path.getFunctionParent() ?? programPath
461
+ if (owner === programPath && cell === undefined && !programState.strict) continue
462
+ const names = nativeVars.get(owner) ?? new Set()
463
+ for (const item of path.node.declarations) for (const identifier of bindingNodes(item.id)) names.add(identifier.name)
464
+ nativeVars.set(owner, names)
465
+ }
466
+ for (const [owner, names] of nativeVars) {
467
+ const body = owner.isProgram() ? owner.node : owner.node.body
468
+ body.body.unshift(t.variableDeclaration('var', [...names].map(name => t.variableDeclarator(t.identifier(name)))))
469
+ }
470
+ if (nativeVars.size > 0) programPath.scope.crawl()
471
+ const rootVar = binding => binding !== undefined && binding.scope === programPath.scope && varNames.has(binding.identifier.name)
472
+ const shadowedByWith = (path, binding) => {
473
+ for (let current = path.parentPath; current !== null; current = current.parentPath) {
474
+ if (current.node === binding?.scope.block) return false
475
+ if (current.isWithStatement() && current.get('body').isAncestor(path)) return true
476
+ }
477
+ return false
478
+ }
479
+ const reference = (path, name, deferred = false) => call(capture(path, stateFor(path)), deferred ? 'deferredReference' : 'reference', [t.stringLiteral(name),
480
+ ...isWrite(path) && cell?.writeTarget !== undefined ? [t.stringLiteral(cell.writeTarget(path.node))] : []])
481
+ const lexicalContext = (path, environment) => {
482
+ const owner = lexicalOwner(path)
483
+ const properties = []
484
+ if (owner !== null && !owner.isFunction()) {
485
+ properties.push(t.objectProperty(t.identifier('getThis'), t.arrowFunctionExpression([], t.thisExpression())),
486
+ t.objectProperty(t.identifier('getNewTarget'), t.arrowFunctionExpression([], t.metaProperty(t.identifier('new'), t.identifier('target')))),
487
+ t.objectProperty(t.identifier('allowNewTarget'), t.booleanLiteral(true)),
488
+ t.objectProperty(t.identifier('forbidArguments'), t.booleanLiteral(true)),
489
+ t.objectProperty(t.identifier('strict'), t.booleanLiteral(true)))
490
+ }
491
+ if (owner !== null && (owner.isClassMethod() || owner.isClassPrivateMethod() || owner.isObjectMethod() || !owner.isFunction())) {
492
+ const key = t.identifier(allocate('super_key'))
493
+ const value = t.identifier(allocate('super_value'))
494
+ const target = t.memberExpression(t.super(), t.cloneNode(key), true)
495
+ properties.push(t.objectProperty(t.identifier('getSuper'), t.arrowFunctionExpression([key], t.objectExpression([
496
+ t.objectProperty(t.identifier('get'), t.arrowFunctionExpression([], t.cloneNode(target))),
497
+ t.objectProperty(t.identifier('set'), t.arrowFunctionExpression([value], t.assignmentExpression('=', t.cloneNode(target), t.cloneNode(value)))),
498
+ ]))))
499
+ if (owner.isClassMethod({ kind: 'constructor' }) && owner.parentPath.parentPath.node.superClass !== null) {
500
+ const args = t.identifier(allocate('super_arguments'))
501
+ properties.push(t.objectProperty(t.identifier('callSuper'), t.arrowFunctionExpression([t.restElement(args)],
502
+ t.callExpression(t.super(), [t.spreadElement(call(t.cloneNode(environment, true), 'internalArray', [t.cloneNode(args)]))]))))
503
+ }
504
+ }
505
+ const visiblePrivate = new Map()
506
+ for (let current = path.parentPath; current !== null; current = current.parentPath) if (current.isClass()) {
507
+ const physicalNames = new Set(current.node.body.body.filter(item => t.isPrivateName(item.key)).map(item => item.key.id.name))
508
+ for (const group of cell?.privateBindings ?? []) {
509
+ for (const name of group.hiddenNames ?? []) physicalNames.delete(name)
510
+ for (const binding of group.names) {
511
+ if (!binding.targets.some(target => physicalNames.has(target.physicalName))) continue
512
+ if (!visiblePrivate.has(binding.name)) visiblePrivate.set(binding.name, { bridgeExpression: binding.bridgeExpression })
513
+ for (const target of binding.targets) physicalNames.delete(target.physicalName)
514
+ }
515
+ }
516
+ for (const name of physicalNames) if (!visiblePrivate.has(name)) {
517
+ visiblePrivate.set(name, { physicalName: name })
518
+ }
519
+ }
520
+ if (visiblePrivate.size > 0) properties.push(t.objectProperty(t.identifier('privateReferences'), t.objectExpression([...visiblePrivate].map(([name, { physicalName, bridgeExpression }]) => {
521
+ const receiver = t.identifier(allocate('private_receiver'))
522
+ const value = t.identifier(allocate('private_value'))
523
+ if (bridgeExpression !== undefined) {
524
+ // The scope normalizer owns logical private member selection, names,
525
+ // and write rules. Retain its adapter in the original class context.
526
+ const bridge = parseExpression(bridgeExpression, { errorRecovery: true })
527
+ const access = () => member(t.callExpression(t.cloneNode(bridge), [t.cloneNode(receiver)]), 'v')
528
+ return t.objectProperty(t.stringLiteral(name), t.arrowFunctionExpression([receiver], t.objectExpression([
529
+ t.objectProperty(t.identifier('get'), t.arrowFunctionExpression([], access())),
530
+ t.objectProperty(t.identifier('set'), t.arrowFunctionExpression([value], t.assignmentExpression('=', access(), t.cloneNode(value)))),
531
+ t.objectProperty(t.identifier('has'), t.arrowFunctionExpression([], t.callExpression(t.cloneNode(bridge), [
532
+ t.cloneNode(receiver), t.booleanLiteral(false), t.booleanLiteral(true),
533
+ ]))),
534
+ ])))
535
+ }
536
+ const key = t.privateName(t.identifier(physicalName))
537
+ const target = t.memberExpression(t.cloneNode(receiver), t.cloneNode(key))
538
+ return t.objectProperty(t.stringLiteral(name), t.arrowFunctionExpression([receiver], t.objectExpression([
539
+ t.objectProperty(t.identifier('get'), t.arrowFunctionExpression([], t.cloneNode(target))),
540
+ t.objectProperty(t.identifier('set'), t.arrowFunctionExpression([value], t.assignmentExpression('=', t.cloneNode(target), t.cloneNode(value)))),
541
+ t.objectProperty(t.identifier('has'), t.arrowFunctionExpression([], t.binaryExpression('in', key, t.cloneNode(receiver)))),
542
+ ])))
543
+ }))))
544
+ return properties.length === 0 ? environment : call(environment, 'context', [t.objectExpression(properties)])
545
+ }
546
+ const replaceReference = (path, resolved, optional = false) => {
547
+ const callable = ((path.parentPath.isCallExpression() || path.parentPath.isOptionalCallExpression()) && path.key === 'callee')
548
+ || path.parentPath.isTaggedTemplateExpression() && path.key === 'tag'
549
+ replace(path, operations.value(optional ? t.optionalMemberExpression(resolved, t.identifier(callable ? 'callee' : 'value'), false, true)
550
+ : member(resolved, callable ? 'callee' : 'value')))
551
+ path.skip()
552
+ }
553
+ // Marker callbacks address compiler-owned storage. Expand them with their
554
+ // actual source environment while keeping that storage out of user lookup.
555
+ traverse(tree, { CallExpression(path) {
556
+ if (!declarationMarker(path.node)) return
557
+ replace(path, call(capture(path, stateFor(path)), 'withReference', path.node.arguments))
558
+ path.skip()
559
+ } })
560
+ traverse(tree, {
561
+ enter(path) {
562
+ if (generated.has(path.node) || path.isTSType()
563
+ || internalDeclaration(path)
564
+ || cell !== undefined && path.isVariableDeclarator() && path.node.id.name === environmentName) path.skip()
565
+ },
566
+ CallExpression: { exit(path) {
567
+ if (cell === undefined && path.node.callee.type === 'Import') {
568
+ replace(path, call(stateFor(path).id, 'importModule', path.node.arguments))
569
+ return
570
+ }
571
+ if (!t.isIdentifier(path.node.callee, { name: 'eval' })) return
572
+ const state = stateFor(path)
573
+ const callee = call(capture(path, state), 'reference', [t.stringLiteral('eval')])
574
+ const invocationOrigin = callOrigin(path.node)
575
+ const origin = invocationOrigin.target
576
+ const environment = lexicalContext(path, origin === undefined ? capture(path, state) : call(capture(path, state), 'at', [t.stringLiteral(origin)]))
577
+ replace(path, t.callExpression(t.callExpression(member(callee, 'evalInvocation'), [environment,
578
+ t.arrayExpression(path.node.arguments), t.valueToNode(invocationOrigin)]), []))
579
+ path.skip()
580
+ } },
581
+ 'TSAsExpression|TSSatisfiesExpression|TSNonNullExpression|TSTypeAssertion': { exit(path) {
582
+ // These wrappers have no runtime operation. Erase them after reference
583
+ // ownership has been resolved, before code generation changes precedence.
584
+ path.replaceWith(path.node.expression)
585
+ } },
586
+ 'MemberExpression|OptionalMemberExpression': { exit(path) {
587
+ if (externalPrivate.has(path.node.property.start)) {
588
+ const resolved = call(stateFor(path).id, 'privateReference', [t.stringLiteral(path.node.property.id.name), path.node.object,
589
+ t.booleanLiteral(path.node.optional === true)])
590
+ replaceReference(path, resolved, path.node.optional === true)
591
+ } else if (t.isSuper(path.node.object) && lexicalOwner(path) === null) {
592
+ const resolved = call(stateFor(path).id, 'superReference', [path.node.computed ? path.node.property : t.stringLiteral(path.node.property.name)])
593
+ replaceReference(path, resolved)
594
+ }
595
+ } },
596
+ BinaryExpression: { exit(path) {
597
+ if (path.node.operator !== 'in' || !t.isPrivateName(path.node.left) || !externalPrivate.has(path.node.left.start)) return
598
+ replace(path, call(stateFor(path).id, 'privateHas', [t.stringLiteral(path.node.left.id.name), path.node.right]))
599
+ path.skip()
600
+ } },
601
+ Super(path) {
602
+ if (lexicalOwner(path) !== null || !path.parentPath.isCallExpression()) return
603
+ if (!allowSuperCall) throw new SyntaxError('super() is only valid in a derived constructor')
604
+ replace(path, member(stateFor(path).id, 'superCall'))
605
+ path.skip()
606
+ },
607
+ Identifier(path) {
608
+ if (path.parentPath.isCallExpression() && path.key === 'callee' && path.node.name === 'eval') return
609
+ if (!path.isReferencedIdentifier() && !isWrite(path)) return
610
+ // Physical cells and private helpers are compiler-owned lexical names.
611
+ // The normalizer leaves original with-visible references for this pass.
612
+ if (hiddenBindings.has(path.node.name) || logicalBindings.has(path.node.name)) return
613
+ if (forbidArguments && path.node.name === 'arguments' && lexicalOwner(path) === null) throw new SyntaxError("'arguments' is not allowed in class field initializer or static initialization block")
614
+ const binding = sourceBinding(path, path.node.name)
615
+ const state = stateFor(path)
616
+ const selfReference = isSelfBinding(binding) && (bodyBindingKind(binding) === undefined || sourceInParameters(path, binding.scope))
617
+ const awaitRootBinding = cell?.nativeAwait === true && binding?.scope === programPath.scope
618
+ const withShadow = shadowedByWith(path, binding)
619
+ if (binding !== undefined && !rootVar(binding) && !awaitRootBinding && !withShadow
620
+ && !dynamicScopeAnalysis.mayEvalShadow(path, binding.scope.block, selfReference)) return
621
+ if (path.node.name === 'arguments') {
622
+ const fn = path.findParent(parent => parent.isFunction() && !parent.isArrowFunctionExpression())
623
+ if (fn !== null && !functionScopes.get(fn.scope)?.parameters && !shadowedByWith(path, { scope: fn.scope })) return
624
+ }
625
+ const deferred = isWrite(path)
626
+ && (withShadow || dynamicScopeAnalysis.mayEvalShadow(path, binding?.scope.block, selfReference))
627
+ const resolved = reference(path, path.node.name, deferred)
628
+ if (path.parentPath.isUnaryExpression({ operator: 'typeof' })) {
629
+ replace(path.parentPath, call(resolved, 'typeof'))
630
+ path.parentPath.skip()
631
+ } else if (path.parentPath.isUnaryExpression({ operator: 'delete' })) {
632
+ replace(path.parentPath, call(resolved, 'delete'))
633
+ path.parentPath.skip()
634
+ } else {
635
+ const callable = ((path.parentPath.isCallExpression() || path.parentPath.isOptionalCallExpression()) && path.key === 'callee')
636
+ || path.parentPath.isTaggedTemplateExpression() && path.key === 'tag'
637
+ if (path.parentPath.isObjectProperty() && path.parent.shorthand) {
638
+ path.parent.shorthand = false
639
+ path.parent.computed = true
640
+ path.parent.key = t.stringLiteral(path.node.name)
641
+ }
642
+ replace(path, operations.value(member(resolved, callable ? 'callee' : 'value')))
643
+ path.skip()
644
+ }
645
+ },
646
+ ThisExpression(path) {
647
+ if (cell !== undefined) return
648
+ const fn = lexicalOwner(path)
649
+ if (fn !== null) return
650
+ replace(path, operations.value(call(stateFor(path).id, 'thisValue')))
651
+ path.skip()
652
+ },
653
+ MetaProperty(path) {
654
+ if (cell !== undefined) return
655
+ if (path.node.meta.name !== 'new' || path.node.property.name !== 'target') return
656
+ const fn = lexicalOwner(path)
657
+ if (fn !== null) return
658
+ replace(path, operations.value(call(stateFor(path).id, 'newTarget')))
659
+ path.skip()
660
+ },
661
+ })
662
+ if (cell?.nativeAwait === true) rewriteNativeAwaitDeclarations(tree, {
663
+ hiddenBindings, nativePlaceholders, namedValue,
664
+ replaceIterationDeclaration: (path, target, initializers) => replaceIterationDeclaration(path, target, initializers, allocate, true),
665
+ reference: (path, name) => member(reference(path, name), 'value'),
666
+ initialize: (path, name, value) => call(capture(path, stateFor(path)), 'initialize', [t.stringLiteral(name), value]),
667
+ })
668
+ for (const plan of creationPlans) plan.environment = capture(plan.path.parentPath, plan.parent, plan.path)
669
+ for (const path of varDeclarations.reverse()) {
670
+ const redirectPattern = node => {
671
+ if (t.isIdentifier(node)) return member(call(capture(path, stateFor(path)), 'deferredReference', [t.stringLiteral(node.name)]), 'value')
672
+ if (t.isArrayPattern(node)) return t.arrayPattern(node.elements.map(element => element === null ? null : redirectPattern(element)))
673
+ if (t.isObjectPattern(node)) return t.objectPattern(node.properties.map(property => t.isRestElement(property)
674
+ ? t.restElement(redirectPattern(property.argument))
675
+ : t.objectProperty(property.key, redirectPattern(property.value), property.computed, false)))
676
+ if (t.isAssignmentPattern(node)) return t.assignmentPattern(redirectPattern(node.left),
677
+ t.isIdentifier(node.left) ? namedValue(node.left.name, node.right) : node.right)
678
+ return t.restElement(redirectPattern(node.argument))
679
+ }
680
+ const expressions = path.node.declarations.filter(item => item.init !== null)
681
+ .map(item => t.isIdentifier(item.id)
682
+ ? call(capture(path, stateFor(path)), 'initialize', [t.stringLiteral(item.id.name), namedValue(item.id.name, item.init)])
683
+ : t.assignmentExpression('=', redirectPattern(item.id), item.init))
684
+ if (path.parentPath.isForOfStatement() || path.parentPath.isForInStatement()) {
685
+ replaceIterationDeclaration(path, redirectPattern(path.node.declarations[0].id), expressions, allocate)
686
+ } else if (path.parentPath.isForStatement()) {
687
+ path.replaceWith(expressions.length === 0 ? t.unaryExpression('void', t.numericLiteral(0)) : t.sequenceExpression(expressions))
688
+ } else path.replaceWith(t.variableDeclaration('let', [t.variableDeclarator(t.identifier(allocate('eval_declaration')),
689
+ expressions.length === 0 ? null : t.sequenceExpression(expressions))]))
690
+ }
691
+ for (const plan of functionPlans.reverse()) {
692
+ const { path, parent, state, scope, node, arrow } = plan
693
+ let parentEnvironment = plan.parameters ? parameterEnvironment(plan) : capture(path.parentPath, parent, path)
694
+ const setup = []
695
+ const nativeArguments = !arrow && scope.getOwnBinding('arguments')?.kind === 'var'
696
+ if (plan.parameters && (nativeArguments || plan.parameterInitializers.length > 0)) {
697
+ const parameterFrame = t.identifier(allocate('parameter_frame'))
698
+ setup.push(t.variableDeclaration('const', [t.variableDeclarator(parameterFrame, parentEnvironment)]))
699
+ if (nativeArguments) setup.push(t.expressionStatement(t.assignmentExpression('=', t.identifier('arguments'),
700
+ member(call(parameterFrame, 'reference', [t.stringLiteral('arguments')]), 'value'))))
701
+ for (const initializer of plan.parameterInitializers) {
702
+ initializer.node.init = member(call(parameterFrame, 'reference', [t.stringLiteral(initializer.name)]), 'value')
703
+ }
704
+ parentEnvironment = parameterFrame
705
+ }
706
+ const activationBindings = descriptorMap(scope, !arrow && !plan.parameters, new Set(), state.strict)
707
+ const selfBindings = plan.parameters ? undefined : selfBindingsFor(plan)
708
+ const activation = call(parentEnvironment, 'activation', [activationBindings,
709
+ arrow ? undefinedValue() : t.arrowFunctionExpression([], t.thisExpression()),
710
+ arrow ? undefinedValue() : t.arrowFunctionExpression([], t.metaProperty(t.identifier('new'), t.identifier('target'))),
711
+ t.booleanLiteral(state.strict), t.booleanLiteral(!arrow), ...(selfBindings === undefined ? [] : [selfBindings])])
712
+ const declaration = t.variableDeclaration('const', [t.variableDeclarator(t.cloneNode(state.id), activation)])
713
+ if (node.body.type === 'BlockStatement') node.body.body.unshift(...setup, declaration)
714
+ else node.body = t.blockStatement([declaration, t.returnStatement(node.body)])
715
+ if (plan.parameters && arrow) {
716
+ // Arrow-internal comments include source identity marks. Babel would
717
+ // inherit them onto the replacement call, outside the actual callable.
718
+ if (node.innerComments !== undefined) {
719
+ t.addComments(node.body.body[0], 'leading', node.innerComments)
720
+ delete node.innerComments
721
+ }
722
+ path.replaceWith(call(capture(path.parentPath, parent), 'parameterArrow', [
723
+ plan.inferredKey === undefined ? node : namedValue(plan.inferredKey, node)]))
724
+ }
725
+ }
726
+ for (const { path, parent, state } of withPlans.reverse()) {
727
+ const initialization = call(capture(path, parent), 'withObject', [path.node.object])
728
+ path.replaceWith(t.blockStatement([
729
+ t.variableDeclaration('const', [t.variableDeclarator(t.cloneNode(state.id), initialization)]), path.node.body,
730
+ ]))
731
+ }
732
+ for (const path of annexPublications) path.insertAfter(t.variableDeclaration('const', [
733
+ t.variableDeclarator(t.identifier(allocate('eval_function')), call(incoming, 'initializeEvalFunction', [
734
+ t.stringLiteral(path.node.id.name), t.identifier(path.node.id.name),
735
+ ])),
736
+ ]))
737
+ const functionValues = new Map()
738
+ for (const path of functions) {
739
+ const node = path.node
740
+ const name = node.id.name
741
+ const expression = t.functionExpression(null, node.params, node.body, node.generator, node.async)
742
+ const named = namedValue(name, expression)
743
+ functionValues.set(name, named)
744
+ path.replaceWith(t.emptyStatement())
745
+ }
746
+ for (const { path, environment, state } of creationPlans.reverse()) {
747
+ let value = path.node
748
+ if (t.isArrowFunctionExpression(value) || (t.isFunctionExpression(value) || t.isClassExpression(value)) && value.id === null) {
749
+ const key = inferredCallableKey(path)
750
+ if (key !== undefined) value = namedValue(key, value)
751
+ }
752
+ path.replaceWith(t.callExpression(t.arrowFunctionExpression([state.id], value), [environment]))
753
+ }
754
+ if (cell === undefined) {
755
+ const initializers = varNames.size === 0 ? [] : [t.variableDeclaration('const', [
756
+ t.variableDeclarator(t.identifier(allocate('eval_declarations')), call(incoming, 'initializeEvalDeclarations', [
757
+ t.arrayExpression([...varNames].map(name => t.arrayExpression([t.stringLiteral(name),
758
+ ...(functionValues.has(name) ? [functionValues.get(name), t.booleanLiteral(true)] : [])]))),
759
+ ])),
760
+ ])]
761
+ const captureRoot = call(incoming, 'capture', [t.arrayExpression([descriptorMap(programPath.scope, false, varNames)]), t.booleanLiteral(programState.strict)])
762
+ tree.program.body.unshift(t.variableDeclaration('const', [t.variableDeclarator(t.cloneNode(programState.id), captureRoot)]), ...initializers)
763
+ }
764
+ if (strict && !tree.program.directives.some(directive => directive.value.value === 'use strict')) {
765
+ tree.program.directives.unshift(t.directive(t.directiveLiteral('use strict')))
766
+ }
767
+ operations.generated(tree)
768
+ for (const name of hiddenBindings) operations.internal.add(name)
769
+ rewriteNativeCalls(tree, incoming, {
770
+ operations, allocate,
771
+ origin: callOrigin,
772
+ skip: path => nativePlaceholders.has(path.node) || t.isFunction(path.node) && generated.has(path.node)
773
+ || internalDeclaration(path),
774
+ })
775
+ const result = transformFromAstSync(tree, source, { babelrc: false, configFile: false, browserslistConfigFile: false, sourceMaps: true,
776
+ cloneInputAst: false, generatorOpts: { compact: cell?.compactOutput === true } })
777
+ return { code: result.code, sourceMap: result.map, environmentName, varNames: [...varNames],
778
+ callableSources: marked === undefined ? [] : collectCallableSources(result.code, marked.callableSources, parserOptions) }
779
+ }