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
@@ -1,15 +1,10 @@
1
- import { stripTypeScriptTypes } from 'node:module'
1
+ import { ModuleRewriteError } from './cell-rewriter.js'
2
+ import { declarationSpan, PreflightError } from './cell-analysis-contract.js'
3
+ export { declarationSpan, PreflightError } from './cell-analysis-contract.js'
2
4
  import { parse } from 'acorn'
3
- import {
4
- STRIP_PREFIX,
5
- STRIP_SUFFIX,
6
- rewriteModuleImportsExports,
7
- } from './cell-rewriter.js'
8
- import {
9
- LEGACY_DEFAULT_EXPORT_BINDING,
10
- LIVE_DEFAULT_EXPORT_BINDING,
11
- redeclarationCommitTarget,
12
- } from './repl-rewrite-contract.js'
5
+ import { parse as parseSource } from '@babel/parser'
6
+ import { parseExecutableCell } from './cell-parser.js'
7
+ import { redeclarationCommitTarget } from './repl-rewrite-contract.js'
13
8
  import {
14
9
  bindingNodes,
15
10
  createGeneratedNameAllocator,
@@ -22,9 +17,15 @@ import {
22
17
  renderDurabilityReason,
23
18
  renderDurabilityReasons,
24
19
  } from './module-policy.js'
25
- import { rewriteReplRedeclarations } from './repl-convenience.js'
26
- import { applySourceEdits, mapSourceSpan } from './source-position-map.js'
20
+ import { applySourceEdits, mapSourcePosition, mapSourceSpan, sourceRangeHasOriginalText } from './source-position-map.js'
27
21
  import { SKIP_AST_CHILDREN, walkAst } from './ast-traversal.js'
22
+ import { compileStatefulRoot } from './stateful-root-compiler.js'
23
+ import { CELL_PARSER_PLUGINS, bindCompilerIntrinsics, lowerStatefulDecorators, lowerStatefulResources, lowerNativeLanguageSource, normalizeStatefulScopes } from './repl-scope-normalizer.js'
24
+ import { markCallableSources, collectCallableSources } from './callable-source-facts.js'
25
+ import { LegacyPreflightError, prepareLegacyProgram } from './legacy-cell-analysis.js'
26
+ import { adaptLegacyModuleImports } from './managed-module-operations.js'
27
+ import { adaptNativeRootDynamic } from './native-root-compilation.js'
28
+ import { sourceRegionData } from './compiler-region-output.js'
28
29
 
29
30
  /**
30
31
  * Pure AST analysis for PTC cells: binding inventory, durability classification,
@@ -32,24 +33,6 @@ import { SKIP_AST_CHILDREN, walkAst } from './ast-traversal.js'
32
33
  * or session state so its behavior is fully testable in isolation.
33
34
  */
34
35
 
35
- export function declarationSpan(node) {
36
- const start = node.loc?.start
37
- /* c8 ignore next */
38
- const end = node.loc?.end ?? start
39
- /* c8 ignore next */
40
- if (start === undefined) return undefined
41
- return {
42
- line: Math.max(1, start.line - 1),
43
- column: start.column + 1,
44
- /* c8 ignore next */
45
- ...(end === undefined ? {} : {
46
- end: {
47
- line: Math.max(1, end.line - 1),
48
- column: end.column + 1,
49
- },
50
- }),
51
- }
52
- }
53
36
 
54
37
  function addPatternBindings(pattern, names) {
55
38
  walkPattern(pattern, node => names.add(node.name))
@@ -69,10 +52,26 @@ function topLevelBindings(body) {
69
52
  return new Set(topLevelDeclarations(body).map(declaration => declaration.name))
70
53
  }
71
54
 
55
+ function rootVarDeclarations(body, declarations, seen) {
56
+ walkAst({ type: 'Program', body }, node => {
57
+ if (node.type === 'VariableDeclaration' && node.kind === 'var' && !seen.has(node)) {
58
+ seen.add(node)
59
+ const definitionSpan = declarationSpan(node)
60
+ for (const declaration of node.declarations) {
61
+ addPatternDeclarations(declaration.id, declarations, 'variable', definitionSpan, true)
62
+ }
63
+ }
64
+ if (isFunction(node) || node.type === 'ClassDeclaration' || node.type === 'ClassExpression'
65
+ || node.type === 'StaticBlock') return SKIP_AST_CHILDREN
66
+ })
67
+ }
68
+
72
69
  function topLevelDeclarations(body, variableRedeclarations = false) {
73
70
  const declarations = []
71
+ const seen = new Set()
74
72
  for (const statement of body) {
75
73
  if (statement.type === 'VariableDeclaration') {
74
+ seen.add(statement)
76
75
  const definitionSpan = declarationSpan(statement)
77
76
  for (const declaration of statement.declarations) {
78
77
  addPatternDeclarations(
@@ -95,6 +94,7 @@ function topLevelDeclarations(body, variableRedeclarations = false) {
95
94
  })
96
95
  }
97
96
  }
97
+ rootVarDeclarations(body, declarations, seen)
98
98
  return declarations
99
99
  }
100
100
 
@@ -111,21 +111,56 @@ function directBlockBindings(body) {
111
111
  return names
112
112
  }
113
113
 
114
- function functionBindings(node) {
114
+ function functionParameterBindings(node) {
115
115
  const names = new Set()
116
116
  if (node.id !== null && node.id !== undefined) names.add(node.id.name)
117
117
  /* c8 ignore next */
118
118
  for (const param of node.params ?? []) addPatternBindings(param, names)
119
- walkAst(node.body, (current) => {
120
- if (current !== node && isFunction(current)) {
121
- if (current.type === 'FunctionDeclaration' && current.id !== null) names.add(current.id.name)
119
+ return names
120
+ }
121
+
122
+ function hasStrictDirective(body) {
123
+ if (body.type !== 'BlockStatement') return false
124
+ for (const statement of body.body) {
125
+ if (statement.directive === undefined) break
126
+ if (statement.directive === 'use strict') return true
127
+ }
128
+ return false
129
+ }
130
+
131
+ function addFunctionVariables(body, names, strict) {
132
+ const addBlockFunction = (node, blocked) => {
133
+ if (!strict && node.type === 'FunctionDeclaration' && !node.async && !node.generator
134
+ && !blocked.has(node.id.name)) names.add(node.id.name)
135
+ }
136
+ walkAst(body, (current, parent, key, blocked) => {
137
+ if (isFunction(current)) {
138
+ addBlockFunction(current, blocked)
122
139
  return SKIP_AST_CHILDREN
123
140
  }
141
+ if (current.type === 'StaticBlock') return SKIP_AST_CHILDREN
124
142
  if (current.type === 'VariableDeclaration' && current.kind === 'var') {
125
143
  for (const declaration of current.declarations) addPatternBindings(declaration.id, names)
126
144
  }
127
- })
128
- return names
145
+ const statements = current.type === 'BlockStatement' ? current.body
146
+ : current.type === 'SwitchCase' ? parent.cases.flatMap(branch => branch.consequent) : undefined
147
+ if (statements !== undefined) {
148
+ // Annex B creates a function-scope var only when intervening lexical
149
+ // declarations permit it. The declaration's own block binding is excluded.
150
+ for (const statement of statements) addBlockFunction(statement, blocked)
151
+ return new Set([...blocked, ...directBlockBindings(statements)])
152
+ }
153
+ if (['ForStatement', 'ForInStatement', 'ForOfStatement'].includes(current.type)) {
154
+ return new Set([...blocked, ...loopBindings(current)])
155
+ }
156
+ if (current.type === 'CatchClause' && current.param !== null && current.param.type !== 'Identifier') {
157
+ // The Annex B catch exception admits var names through a simple parameter,
158
+ // but a destructured catch binding still blocks function-scope promotion.
159
+ const nested = new Set(blocked)
160
+ addPatternBindings(current.param, nested)
161
+ return nested
162
+ }
163
+ }, undefined, new Set())
129
164
  }
130
165
 
131
166
  function loopBindings(node) {
@@ -171,10 +206,10 @@ function staticMemberName(node) {
171
206
  return undefined
172
207
  }
173
208
 
174
- function globalThisMember(node) {
209
+ function globalObjectMember(node) {
175
210
  return node?.type === 'MemberExpression'
176
211
  && node.object?.type === 'Identifier'
177
- && node.object.name === 'globalThis'
212
+ && ['global', 'globalThis'].includes(node.object.name)
178
213
  ? staticMemberName(node)
179
214
  : undefined
180
215
  }
@@ -185,12 +220,6 @@ function isFunction(node) {
185
220
  || node.type === 'ArrowFunctionExpression'
186
221
  }
187
222
 
188
- export class PreflightError extends Error {
189
- constructor(message, node, span = undefined) {
190
- super(message)
191
- this.span = span ?? declarationSpan(node)
192
- }
193
- }
194
223
 
195
224
  function staticModuleClassification(moduleLoads) {
196
225
  const reasons = new Map()
@@ -211,15 +240,48 @@ function staticModuleClassification(moduleLoads) {
211
240
  }
212
241
 
213
242
  /** Conservatively classify a cell before giving it non-journalable capability. */
214
- export function classifyDurability(code, knownBindings = new Set()) {
215
- const tree = parse(`${STRIP_PREFIX}${code}${STRIP_SUFFIX}`, { ecmaVersion: 'latest', sourceType: 'script', locations: true })
216
- const outer = tree.body[0]
217
- /* c8 ignore next */
218
- if (outer?.type !== 'FunctionDeclaration') throw new Error('ptc-plus: failed to parse cell wrapper')
219
- const declared = topLevelBindings(outer.body.body)
243
+ export function classifyDurability(code, knownBindings = new Set(), {
244
+ sourceType = 'script', internalModules = new Set(), sourceMap = undefined, originalSource = undefined,
245
+ } = {}) {
246
+ let body
247
+ let moduleLoads = []
248
+ if (sourceType === 'module') {
249
+ const program = parse(code, { ecmaVersion: 'latest', sourceType: 'module', locations: true })
250
+ knownBindings = new Set(knownBindings)
251
+ moduleLoads = program.body.filter(statement => statement.source != null
252
+ && ['ImportDeclaration', 'ExportNamedDeclaration', 'ExportAllDeclaration'].includes(statement.type)
253
+ && !internalModules.has(statement.source.value)).map(statement => ({
254
+ source: statement.source.value, position: declarationSpan(statement.source),
255
+ }))
256
+ body = { type: 'BlockStatement', body: program.body.flatMap(statement => {
257
+ if (statement.type === 'ImportDeclaration') {
258
+ for (const specifier of statement.specifiers) knownBindings.add(specifier.local.name)
259
+ return []
260
+ }
261
+ if (statement.type === 'ExportAllDeclaration') return []
262
+ if (statement.type === 'ExportNamedDeclaration') return statement.declaration === null ? [] : [statement.declaration]
263
+ if (statement.type === 'ExportDefaultDeclaration') return [statement.declaration]
264
+ return [statement]
265
+ }) }
266
+ } else ({ body } = parseExecutableCell(code))
267
+ const declared = topLevelBindings(body.body)
220
268
  const rootBindings = new Set([...knownBindings, ...declared])
269
+ const rootStrict = sourceType === 'module' || hasStrictDirective(body)
270
+ addFunctionVariables(body, rootBindings, rootStrict)
271
+ // A `var` is instantiated with the cell even on the path that never runs its
272
+ // initializer, so it occupies the shared environment but does not by itself
273
+ // replace a name an earlier cell bound.
274
+ const hoistedVars = new Set()
275
+ walkAst(body, (node) => {
276
+ if (isFunction(node)) return SKIP_AST_CHILDREN
277
+ if (node.type === 'StaticBlock') return SKIP_AST_CHILDREN
278
+ if (node.type === 'VariableDeclaration' && node.kind === 'var') {
279
+ for (const declaration of node.declarations) addPatternBindings(declaration.id, hoistedVars)
280
+ }
281
+ })
221
282
  const reasons = new Map()
222
283
  const addReason = reason => reasons.set(renderDurabilityReason(reason), reason)
284
+ for (const reason of staticModuleClassification(moduleLoads)) addReason(reason)
223
285
  const classifyModule = (source) => {
224
286
  if (source?.type !== 'Literal' || typeof source.value !== 'string') {
225
287
  addReason(DYNAMIC_MODULE_REASON)
@@ -237,12 +299,26 @@ export function classifyDurability(code, knownBindings = new Set()) {
237
299
  }
238
300
  return false
239
301
  }
240
- walkAst(outer.body, (node, parent, parentKey, scopes) => {
302
+ walkAst(body, (node, parent, parentKey, { scopes, strict, thisIsGlobal }) => {
241
303
  let nestedScopes = scopes
242
304
  if (isFunction(node)) {
243
- nestedScopes = [...scopes, functionBindings(node)]
244
- } else if (node.type === 'BlockStatement' && node !== outer.body) {
245
- nestedScopes = [...scopes, directBlockBindings(node.body)]
305
+ strict ||= hasStrictDirective(node.body)
306
+ nestedScopes = [...scopes, functionParameterBindings(node)]
307
+ if (node.type !== 'ArrowFunctionExpression') thisIsGlobal = false
308
+ } else if (node.type === 'BlockStatement' && node !== body) {
309
+ const names = directBlockBindings(node.body)
310
+ if (isFunction(parent)) addFunctionVariables(node, names, strict)
311
+ nestedScopes = [...scopes, names]
312
+ } else if (node.type === 'StaticBlock') {
313
+ const names = directBlockBindings(node.body)
314
+ for (const statement of node.body) addFunctionVariables(statement, names, true)
315
+ strict = true
316
+ nestedScopes = [...scopes, names]
317
+ } else if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {
318
+ strict = true
319
+ nestedScopes = [...scopes, new Set(node.id === null ? [] : [node.id.name])]
320
+ } else if (node.type === 'SwitchCase') {
321
+ nestedScopes = [...scopes, directBlockBindings(parent.cases.flatMap(branch => branch.consequent))]
246
322
  } else if (node.type === 'CatchClause') {
247
323
  const names = new Set()
248
324
  addPatternBindings(node.param, names)
@@ -253,6 +329,11 @@ export function classifyDurability(code, knownBindings = new Set()) {
253
329
  if (node.type === 'ImportExpression') {
254
330
  classifyModule(node.source)
255
331
  }
332
+ const sourceOwnedThis = sourceMap === undefined
333
+ || sourceRangeHasOriginalText(sourceMap, code, originalSource, node.start, node.end)
334
+ if (node.type === 'ThisExpression' && thisIsGlobal && sourceOwnedThis) {
335
+ addReason(Object.freeze({ kind: 'ambient', name: 'globalThis' }))
336
+ }
256
337
  if (node.type === 'CallExpression' && node.callee?.type === 'Identifier' && node.callee.name === 'require'
257
338
  && !isBound('require', nestedScopes)) {
258
339
  classifyModule(node.arguments[0])
@@ -266,279 +347,161 @@ export function classifyDurability(code, knownBindings = new Set()) {
266
347
  && !isBound('process', nestedScopes) && node.name === 'process' && !isStableProcessMember(node, parent)) {
267
348
  addReason(Object.freeze({ kind: 'ambient', name: 'process' }))
268
349
  }
350
+ if (node.type === 'Identifier' && ['global', 'globalThis'].includes(node.name)
351
+ && isReferenceIdentifier(node, parent, parentKey) && !isBound(node.name, nestedScopes)
352
+ && !(parent?.type === 'MemberExpression' && parent.object === node)) {
353
+ addReason(Object.freeze({ kind: 'ambient', name: node.name }))
354
+ }
355
+ if (node.type === 'Identifier' && node.name === 'Math'
356
+ && isReferenceIdentifier(node, parent, parentKey) && !isBound('Math', nestedScopes)
357
+ && !(parent?.type === 'MemberExpression' && parent.object === node && staticMemberName(parent) !== undefined)) {
358
+ addReason(Object.freeze({ kind: 'ambient', name: 'Math' }))
359
+ }
269
360
  if (node.type === 'MemberExpression'
270
361
  && ((node.object?.type === 'Identifier' && node.object.name === 'Math' && !isBound('Math', nestedScopes))
271
- || (globalThisMember(node.object) === 'Math' && !isBound('globalThis', nestedScopes)))
362
+ || (globalObjectMember(node.object) === 'Math' && !isBound(node.object.object.name, nestedScopes)))
272
363
  && staticMemberName(node) === 'random') {
273
364
  addReason(Object.freeze({ kind: 'math-random' }))
274
365
  }
275
366
  if (node.type === 'MemberExpression' && node.object?.type === 'Identifier'
276
- && node.object.name === 'globalThis' && !isBound('globalThis', nestedScopes)) {
367
+ && ['global', 'globalThis'].includes(node.object.name) && !isBound(node.object.name, nestedScopes)) {
277
368
  const member = staticMemberName(node)
278
369
  if (member === undefined) addReason(Object.freeze({ kind: 'computed-global-access' }))
279
370
  else if (member === 'process') addReason(Object.freeze({ kind: 'ambient', name: 'process' }))
280
371
  else if (AMBIENT_GLOBALS.has(member)) addReason(Object.freeze({ kind: 'ambient', name: member }))
372
+ else if (member === 'global' || member === 'globalThis') addReason(Object.freeze({ kind: 'ambient', name: member }))
373
+ else if (member === 'Math' && !(parent?.type === 'MemberExpression' && parent.object === node
374
+ && staticMemberName(parent) !== undefined)) {
375
+ addReason(Object.freeze({ kind: 'ambient', name: 'Math' }))
376
+ }
281
377
  }
282
- return nestedScopes
283
- }, undefined, [rootBindings], outer, 'body')
378
+ return { scopes: nestedScopes, strict, thisIsGlobal }
379
+ }, undefined, { scopes: [rootBindings], strict: rootStrict, thisIsGlobal: sourceType === 'script' })
284
380
  return {
285
381
  durability: reasons.size === 0 ? 'durable' : 'volatile',
286
382
  reasons: Object.freeze([...reasons.values()]),
287
383
  declared,
384
+ hoistedVars,
288
385
  }
289
386
  }
290
387
 
291
388
  function rewriteCellReturns(code, sourceMap, unavailableNames) {
292
- const wrapped = STRIP_PREFIX + code + STRIP_SUFFIX
293
- const tree = parse(wrapped, { ecmaVersion: 'latest', sourceType: 'script' })
294
- const outer = tree.body[0]
295
- /* c8 ignore next */
296
- if (outer?.type !== 'FunctionDeclaration') throw new Error('ptc-plus: failed to parse cell wrapper')
297
- const offset = STRIP_PREFIX.length
389
+ const { body } = parseExecutableCell(code)
298
390
  const edits = []
299
- const allocateName = createGeneratedNameAllocator(tree, unavailableNames)
391
+ const allocateName = createGeneratedNameAllocator(body, unavailableNames)
300
392
  const returnSignal = allocateName('return_signal')
301
393
  const signalReference = `this[${JSON.stringify(returnSignal)}]`
394
+ const completion = allocateName('cell_completion')
395
+ const exit = allocateName('cell_exit')
396
+ const ignored = allocateName('completion_effect')
397
+ let asyncCompletion = false
302
398
 
303
- walkAst(outer.body, (node) => {
304
- if (node !== outer.body && isFunction(node)) return SKIP_AST_CHILDREN
399
+ walkAst(body, (node) => {
400
+ if (node !== body && isFunction(node)) return SKIP_AST_CHILDREN
401
+ if (node.type === 'AwaitExpression' || node.await === true
402
+ || node.type === 'VariableDeclaration' && node.kind === 'await using') asyncCompletion = true
305
403
  if (node.type === 'ReturnStatement') {
306
- const start = node.start - offset
307
- const end = node.end - offset
404
+ const start = node.start
405
+ const end = node.end
308
406
  const argument = node.argument === null
309
407
  ? ''
310
- : code.slice(node.argument.start - offset, node.argument.end - offset)
311
- // A ReturnStatement may be the last clause body in a switch case. The
312
- // generated throw must terminate explicitly because the original return
313
- // statement's semicolon is part of the replaced AST range.
314
- edits.push({ start, end, text: `throw new ${signalReference}(${argument});` })
315
- return SKIP_AST_CHILDREN
316
- }
317
- if (node.type === 'CatchClause') {
318
- const bodyStart = node.body.start - offset + 1
319
- const temporary = allocateName('caught')
320
- if (node.param === null) {
321
- edits.push({ start: node.start - offset + 5, end: node.start - offset + 5, text: ` (${temporary})` })
322
- edits.push({ start: bodyStart, end: bodyStart, text: `\nif (${temporary} instanceof ${signalReference}) throw ${temporary};` })
323
- } else if (node.param.type === 'Identifier') {
324
- edits.push({
325
- start: bodyStart,
326
- end: bodyStart,
327
- text: `\nif (${node.param.name} instanceof ${signalReference}) throw ${node.param.name};`,
328
- })
329
- } else {
330
- const pattern = code.slice(node.param.start - offset, node.param.end - offset)
331
- edits.push({ start: node.param.start - offset, end: node.param.end - offset, text: temporary })
332
- edits.push({
333
- start: bodyStart,
334
- end: bodyStart,
335
- text: `\nif (${temporary} instanceof ${signalReference}) throw ${temporary};\nconst ${pattern} = ${temporary};`,
336
- })
337
- }
408
+ : code.slice(node.argument.start, node.argument.end)
409
+ // Break leaves resource and finally scopes without making disposal
410
+ // suppress a private error for an otherwise successful return.
411
+ edits.push({ start, end, text: `{let ${ignored}=(${completion}=new ${signalReference}(${argument}));break ${exit};}` })
338
412
  }
339
413
  })
340
414
 
341
- /* c8 ignore next */
342
- edits.sort((left, right) => right.start - left.start || right.end - left.end)
343
- return { ...applySourceEdits(code, sourceMap, edits), returnSignal }
415
+ const directiveEnd = body.body.findLast(node => node.directive !== undefined)?.end ?? 0
416
+ // Fallthrough cancels a return overridden by finally break/continue. Empty
417
+ // declaration completions preserve the source's ordinary expression value.
418
+ edits.push({ start: directiveEnd, end: directiveEnd,
419
+ text: `\n{let ${completion};${exit}:{\n` })
420
+ edits.push({ start: code.length, end: code.length,
421
+ text: `\n;{let ${ignored}=(${completion}=void 0);}}{let ${ignored}=${completion}&&(()=>{throw ${completion}})();}}\n` })
422
+ let lowered = applySourceEdits(code, sourceMap, edits)
423
+ if (asyncCompletion) {
424
+ // The frame result is compiler-owned transport. Letting Node create it
425
+ // would hide the promise from our observer and re-enter source protocols
426
+ // when the host REPL awaits this realm's completion.
427
+ lowered = applySourceEdits(lowered.code, lowered.sourceMap, [
428
+ { start: 0, end: 0, text: '(async()=>{' },
429
+ { start: lowered.code.length, end: lowered.code.length, text: '\n})()' },
430
+ ])
431
+ }
432
+ return { ...lowered, returnSignal, asyncCompletion }
433
+ }
434
+
435
+ /** Workbench completion uses the same source grammar and compilation boundary. */
436
+ export function prepareConsoleProgram(source, options) {
437
+ const program = parseSource(source, { sourceType: 'script', errorRecovery: true,
438
+ allowImportExportEverywhere: true, allowUndeclaredExports: true,
439
+ allowAwaitOutsideFunction: true, allowReturnOutsideFunction: true, plugins: CELL_PARSER_PLUGINS }).program
440
+ const last = program.body.at(-1)
441
+ const input = last?.type !== 'ExpressionStatement' ? source
442
+ : `${source.slice(0, last.start)}return (${source.slice(last.expression.start, last.expression.end)});${source.slice(last.end)}`
443
+ return prepareProgram(input, options)
344
444
  }
345
445
 
346
- export function prepareProgram(program, knownBindings, bindingPolicy, reservedBindings = new Set(), rewritesEnabled, importBindings = new Map(), importNamespaces = new Set(), writableBindings = undefined, moduleSemantics = { defaultExportBinding: LIVE_DEFAULT_EXPORT_BINDING }) {
446
+ export function prepareProgram(program, options = {}) {
347
447
  if (typeof program !== 'string') throw new TypeError('ptc-plus: program must be a string')
348
- if (typeof bindingPolicy === 'boolean') {
349
- bindingPolicy = {
350
- variableRedeclarations: bindingPolicy,
351
- functionClassRedeclarations: false,
352
- }
353
- }
354
- if (bindingPolicy === null || typeof bindingPolicy !== 'object' || Array.isArray(bindingPolicy)
355
- || typeof bindingPolicy.variableRedeclarations !== 'boolean'
356
- || typeof bindingPolicy.functionClassRedeclarations !== 'boolean') {
357
- throw new TypeError('ptc-plus: binding policy must define variableRedeclarations and functionClassRedeclarations booleans')
358
- }
359
- writableBindings ??= bindingPolicy.variableRedeclarations ? new Set(knownBindings) : new Set()
360
- if (rewritesEnabled === null || typeof rewritesEnabled !== 'object' || Array.isArray(rewritesEnabled)
361
- || typeof rewritesEnabled.autoRewriteImports !== 'boolean'
362
- || typeof rewritesEnabled.autoStripExports !== 'boolean'
363
- || typeof rewritesEnabled.autoSplitRedeclarations !== 'boolean') {
364
- throw new TypeError('ptc-plus: rewrite policy must define autoRewriteImports, autoStripExports, and autoSplitRedeclarations booleans')
365
- }
366
- if (moduleSemantics === null || typeof moduleSemantics !== 'object' || Array.isArray(moduleSemantics)
367
- || ![LEGACY_DEFAULT_EXPORT_BINDING, LIVE_DEFAULT_EXPORT_BINDING]
368
- .includes(moduleSemantics.defaultExportBinding)) {
369
- throw new TypeError('ptc-plus: module semantics must define a supported defaultExportBinding')
370
- }
371
- const unavailableGeneratedNames = new Set([
372
- ...knownBindings,
373
- ...reservedBindings,
374
- ...importBindings.keys(),
375
- ...importNamespaces,
376
- ])
377
- const moduleRewrite = rewriteModuleImportsExports(
378
- program,
379
- rewritesEnabled,
380
- importBindings,
381
- importNamespaces,
382
- unavailableGeneratedNames,
383
- moduleSemantics,
384
- )
385
- const staticModuleReasons = staticModuleClassification(moduleRewrite.moduleLoads)
386
- const wrapped = STRIP_PREFIX + moduleRewrite.code + STRIP_SUFFIX
387
- let stripped = wrapped
388
- let tree
389
- try {
390
- tree = parse(wrapped, { ecmaVersion: 'latest', sourceType: 'script', locations: true })
391
- } catch (javascriptError) {
392
- try {
393
- stripped = stripTypeScriptTypes(wrapped)
394
- tree = parse(stripped, { ecmaVersion: 'latest', sourceType: 'script', locations: true })
395
- } catch {
396
- throw javascriptError
397
- }
398
- }
399
- const code = stripped.slice(STRIP_PREFIX.length, stripped.length - STRIP_SUFFIX.length)
400
- const sourceMap = moduleRewrite.sourceMap
401
- const outer = tree.body[0]
402
- const commitSignal = moduleRewrite.commitSignal
403
- /* c8 ignore next */
404
- const generatedDeclarations = outer?.type === 'FunctionDeclaration'
405
- ? topLevelDeclarations(outer.body.body, bindingPolicy.variableRedeclarations)
406
- : []
407
- const collisionFor = (declaration) => {
408
- /* c8 ignore next */
409
- const mapped = declaration.original === true ? declaration.span : declaration.span === undefined
410
- ? { line: 1, column: 1 }
411
- : mapSourceSpan(declaration.span, code, program, sourceMap)
412
- return {
413
- name: declaration.name,
414
- kind: declaration.kind,
415
- replaceableByVariableDeclaration: declaration.replaceableByVariableDeclaration === true,
416
- ...(declaration.reason === undefined ? {} : { reason: declaration.reason }),
417
- ...(declaration.commitDependency === undefined
418
- ? {}
419
- : { commitDependency: declaration.commitDependency }),
420
- start: { line: mapped.line, column: mapped.column },
421
- /* c8 ignore next */
422
- ...(mapped.end === undefined ? {} : { end: mapped.end }),
423
- }
424
- }
425
- const classifyPrepared = (preparedCode, preparedSourceMap) => {
448
+ if (options.languageSemantics === undefined || options.languageSemantics === 'legacy-v1') {
426
449
  try {
427
- const classification = classifyDurability(preparedCode, knownBindings)
428
- const reasons = new Map()
429
- for (const reason of [...staticModuleReasons, ...classification.reasons]) {
430
- reasons.set(renderDurabilityReason(reason), reason)
431
- }
432
- return {
433
- ...classification,
434
- durability: reasons.size === 0 ? 'durable' : 'volatile',
435
- reasons: Object.freeze([...reasons.values()]),
436
- reason: renderDurabilityReasons([...reasons.values()]),
437
- }
450
+ // Logical imports have no persistent native namespace slot. Their proved
451
+ // identity enters the native execution environment with the other roots.
452
+ const nativeOptions = { ...options, importBindings: new Map([...options.importBindings ?? []]
453
+ .filter(([name]) => !options.establishedRoots?.has(name) || options.nativeBindings?.has(name))) }
454
+ const prepared = adaptNativeRootDynamic(adaptLegacyModuleImports(prepareLegacyProgram(program, nativeOptions), nativeOptions), options, program)
455
+ return { ...prepared, sourceRegions: sourceRegionData(prepared.sourceRegions), languageSemantics: 'legacy-v1' }
438
456
  } catch (error) {
439
- if (error instanceof PreflightError && error.span !== undefined) {
440
- error.span = mapSourceSpan(error.span, preparedCode, program, preparedSourceMap)
441
- }
457
+ if (error instanceof LegacyPreflightError) throw new PreflightError(error.message, undefined, error.span)
442
458
  throw error
443
459
  }
444
460
  }
445
- const importedNames = new Set(moduleRewrite.imports.keys())
446
- const originalDeclarationNames = new Set(moduleRewrite.exportDeclarations.map(declaration => declaration.name))
447
- const declarations = [
448
- ...moduleRewrite.importDeclarations.map(declaration => ({ ...declaration, writable: false })),
449
- ...moduleRewrite.exportDeclarations.map(declaration => ({
450
- ...declaration,
451
- writable: bindingPolicy.variableRedeclarations,
452
- })),
453
- ...generatedDeclarations
454
- .filter(declaration => !moduleRewrite.generatedNamespaces.has(declaration.name)
455
- && !originalDeclarationNames.has(declaration.name))
456
- .map(declaration => ({
457
- ...declaration,
458
- ...(declaration.definitionSpan === undefined ? {} : {
459
- definitionSpan: mapSourceSpan(declaration.definitionSpan, code, program, sourceMap),
460
- }),
461
- })),
462
- ]
463
- const normalizeClassification = classification => {
464
- const imports = new Map(moduleRewrite.imports)
465
- for (const name of classification.declared) {
466
- if (!moduleRewrite.generatedNamespaces.has(name)) imports.delete(name)
467
- }
468
- return {
469
- ...classification,
470
- imports,
471
- declared: new Set([...classification.declared, ...importedNames]),
472
- }
473
- }
474
- const reserved = declarations.filter(declaration => (
475
- reservedBindings.has(declaration.name)
476
- || moduleRewrite.importNamespaces.has(declaration.name)
477
- || (declaration.kind === 'import' && knownBindings.has(declaration.name))
478
- ))
479
- if (reserved.length > 0) {
480
- const classification = normalizeClassification(classifyPrepared(code, sourceMap))
481
- return {
482
- code,
483
- ...classification,
484
- declarations,
485
- imports: classification.imports,
486
- importNamespaces: moduleRewrite.importNamespaces,
487
- collisions: reserved.map(collisionFor),
488
- redeclared: [],
489
- rewrites: moduleRewrite.rewrites,
490
- moduleLoads: moduleRewrite.moduleLoads,
461
+ if (options.languageSemantics === 'stateful-v1' || options.languageSemantics === 'protected-v1') {
462
+ let normalized
463
+ let prepared
464
+ let callableSources
465
+ const intrinsicContext = { bindings: new Set() }
466
+ try {
467
+ const marked = markCallableSources(program, undefined, { plugins: CELL_PARSER_PLUGINS, allowImportExportEverywhere: true, allowUndeclaredExports: true },
468
+ { lowerNativeSource: lowerNativeLanguageSource, nativeUsing: options.nativeUsing })
469
+ callableSources = marked.callableSources
470
+ normalized = normalizeStatefulScopes(marked.code, marked.sourceMap, { mode: options.languageSemantics,
471
+ nativeJavaScript: marked.nativeJavaScript, deferDecorators: true, deferResources: true, intrinsicContext })
472
+ prepared = compileStatefulRoot(normalized.code, { ...options, sourceMap: normalized.sourceMap,
473
+ internalBindings: normalized.internalBindings, dynamicBindings: normalized.dynamicBindings,
474
+ privateBindings: normalized.privateBindings, originalSource: program })
475
+ } catch (error) {
476
+ if (error instanceof ModuleRewriteError) throw error
477
+ const position = error.loc === undefined ? undefined : { line: error.loc.line, column: error.loc.column + 1 }
478
+ throw new ModuleRewriteError(error.message, normalized === undefined ? position
479
+ : mapSourcePosition(position, normalized.code, program, normalized.sourceMap))
491
480
  }
492
- }
493
- const convenience = rewriteReplRedeclarations({
494
- code,
495
- sourceMap,
496
- body: outer?.type === 'FunctionDeclaration' ? outer.body.body : undefined,
497
- offset: STRIP_PREFIX.length,
498
- knownBindings,
499
- variableRedeclarationBindings: bindingPolicy.variableRedeclarations
500
- ? new Set([...knownBindings].filter(name => !importBindings.has(name)))
501
- : new Set(knownBindings),
502
- writableBindings: new Set([...writableBindings].filter(name => !importBindings.has(name))),
503
- declarations,
504
- declarationSpan,
505
- collisionFor,
506
- bindingPolicy,
507
- autoSplitRedeclarations: rewritesEnabled.autoSplitRedeclarations,
508
- commitSignal,
509
- })
510
- const { executableCode, executableSourceMap, collisions, redeclared, rewrites } = convenience
511
- const commitTargets = new Set(moduleRewrite.commitTargets)
512
- for (const declaration of redeclared) {
513
- if (declaration.kind === 'function' || declaration.kind === 'class') {
514
- commitTargets.add(declaration.commitDependency)
481
+ prepared = { ...prepared, deferredHelpers: normalized.deferredHelpers }
482
+ intrinsicContext.expression = `this[${JSON.stringify(prepared.rootRuntimeName)}].intrinsics`
483
+ const classificationSource = bindCompilerIntrinsics(lowerStatefulDecorators(
484
+ { ...prepared, code: prepared.classificationCode, sourceMap: prepared.classificationSourceMap },
485
+ undefined, intrinsicContext), intrinsicContext)
486
+ prepared = bindCompilerIntrinsics(lowerStatefulDecorators(prepared, undefined, intrinsicContext), intrinsicContext)
487
+ prepared = lowerStatefulResources(prepared, { intrinsicContext, nativeUsing: options.nativeUsing })
488
+ const parsed = parseExecutableCell(prepared.code, { eraseTypes: true })
489
+ const classificationCode = parseExecutableCell(classificationSource.code, { eraseTypes: true }).code
490
+ const classification = classifyDurability(classificationCode,
491
+ new Set([...(options.knownBindings ?? []), ...prepared.declared]), {
492
+ sourceMap: classificationSource.sourceMap,
493
+ originalSource: program,
494
+ })
495
+ const reasons = [...staticModuleClassification(prepared.moduleLoads), ...classification.reasons]
496
+ const lowered = rewriteCellReturns(parsed.code, prepared.sourceMap,
497
+ new Set([...prepared.declared, ...(options.knownBindings ?? [])]))
498
+ prepared.rootBindings.callableSources = collectCallableSources(lowered.code, callableSources)
499
+ return { ...prepared, ...lowered,
500
+ sourceRegions: sourceRegionData(prepared.sourceRegions),
501
+ returnSignal: lowered.returnSignal,
502
+ durability: reasons.length === 0 ? 'durable' : 'volatile', reasons: Object.freeze(reasons),
503
+ reason: renderDurabilityReasons(reasons),
515
504
  }
516
505
  }
517
- // Classification sees the rewritten program so declared bindings reflect the
518
- // split form; it must never see the return rewrite, whose computed
519
- // globalThis access would mark every returning cell volatile.
520
- const classification = normalizeClassification(classifyPrepared(executableCode, executableSourceMap))
521
- let lowered = { code, sourceMap }
522
- if (collisions.length === 0) {
523
- lowered = rewriteCellReturns(
524
- executableCode,
525
- executableSourceMap,
526
- unavailableGeneratedNames,
527
- )
528
- }
529
- return {
530
- code: lowered.code,
531
- sourceMap: lowered.sourceMap,
532
- ...(lowered.returnSignal === undefined ? {} : { returnSignal: lowered.returnSignal }),
533
- ...classification,
534
- declarations,
535
- imports: classification.imports,
536
- importNamespaces: moduleRewrite.importNamespaces,
537
- collisions,
538
- redeclared,
539
- rewrites: [...moduleRewrite.rewrites, ...rewrites],
540
- moduleLoads: moduleRewrite.moduleLoads,
541
- commitSignal,
542
- commitTargets,
543
- }
506
+ throw new TypeError('ptc-plus: unsupported language semantics')
544
507
  }