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.
- package/README.en.md +63 -80
- package/README.md +63 -80
- package/assets/ptc-plus-bindings-en.png +0 -0
- package/assets/ptc-plus-bindings-zh.png +0 -0
- package/assets/ptc-plus-repair-en.png +0 -0
- package/assets/ptc-plus-repair-zh.png +0 -0
- package/assets/ptc-plus-repl-workspace-en.png +0 -0
- package/assets/ptc-plus-repl-workspace-zh.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +30827 -742
- package/compiler-amaro.cjs +5 -0
- package/compiler-amaro.cjs.map +6 -0
- package/compiler-asset-124f80c1bba92ff5fe79cfec6e8ad518f476de4a42514cae3919538887f510e8.txt +1 -0
- package/compiler-assets.json +3 -0
- package/compiler-core.cjs +556 -0
- package/compiler-core.cjs.map +6 -0
- package/compiler-platform.cjs +2 -0
- package/compiler-platform.cjs.map +6 -0
- package/compiler-typescript.cjs +388 -0
- package/compiler-typescript.cjs.map +6 -0
- package/docs/README.md +7 -0
- package/docs/adr/0004-declare-program-bindings-at-the-host.md +1 -1
- package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +5 -3
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +1 -1
- package/docs/adr/0009-bound-expensive-acceptance-default.md +2 -0
- package/docs/adr/0010-session-log-derived-recovery-tips.md +59 -5
- package/docs/adr/0011-isolate-the-local-recovery-tip-provider.md +1 -1
- package/docs/adr/0012-preserve-mixed-destructuring-initialization.md +3 -1
- package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +3 -1
- package/docs/adr/0014-persist-cell-rewrite-policy.md +6 -2
- package/docs/adr/0015-preserve-source-positions-through-rewrites.md +1 -1
- package/docs/adr/0016-archive-resolved-review-findings.md +1 -1
- package/docs/adr/0017-track-the-latest-dsh-public-surface.md +49 -0
- package/docs/adr/0018-use-versioned-fixture-for-ab-benchmark.md +3 -3
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +5 -3
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +12 -0
- package/docs/adr/0023-global-user-bindings.md +104 -0
- package/docs/adr/0024-repl-console-observation.md +33 -0
- package/docs/adr/0025-use-versioned-logical-binding-identities.md +119 -0
- package/docs/adr/0026-persist-the-delivery-verdict-against-the-verified-candidate.md +21 -0
- package/docs/adr/0027-run-the-session-kernel-in-a-killable-helper-process.md +37 -0
- package/docs/adr/0028-attach-to-the-host-ptc-execution-seam.md +103 -0
- package/docs/adr/0029-keep-plugin-unavailability-out-of-the-host-agent-lifecycle.md +27 -0
- package/docs/adr/0030-serve-both-typert-codec-generations-from-one-codec.md +27 -0
- package/docs/architecture.md +77 -21
- package/docs/binding-review-placement-design.md +200 -0
- package/docs/capability-projection.md +1 -1
- package/docs/client-ui.md +95 -19
- package/docs/durability-design.md +28 -10
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +76 -25
- package/docs/semantic-validation.md +29 -0
- package/docs/stateful-binding-updates-proposal.md +759 -0
- package/docs/user-bindings.en.md +66 -0
- package/docs/user-bindings.md +66 -0
- package/docs/value-wire.md +3 -3
- package/docs/verification-optimization-work.md +41 -0
- package/docs/verification.md +71 -0
- package/index.js +369 -92
- package/internal/ast-traversal.js +5 -2
- package/internal/async-local-storage-intrinsics.js +38 -0
- package/internal/binding-declaration-contract.js +8 -0
- package/internal/binding-descriptors.js +1 -0
- package/internal/binding-pattern-traversal.js +25 -0
- package/internal/binding-pattern.js +26 -29
- package/internal/binding-source-analysis.js +708 -0
- package/internal/binding-update-policy.js +72 -0
- package/internal/bounded-worker-round.js +56 -0
- package/internal/callable-definition-environment.js +42 -0
- package/internal/callable-source-catalog.js +129 -0
- package/internal/callable-source-encoding.js +47 -0
- package/internal/callable-source-facts.js +459 -0
- package/internal/callable-source-format.js +2 -0
- package/internal/callable-source-lowering.js +123 -0
- package/internal/cell-analysis-contract.js +25 -0
- package/internal/cell-analysis.js +253 -290
- package/internal/cell-completion.js +15 -0
- package/internal/cell-error.js +7 -0
- package/internal/cell-parser.js +66 -0
- package/internal/cell-rewriter.js +3 -677
- package/internal/commonjs-export-evidence.js +63 -0
- package/internal/commonjs-source-evidence.js +72 -0
- package/internal/compiler-amaro.cjs +2 -0
- package/internal/compiler-compression.js +12 -0
- package/internal/compiler-data.js +58 -0
- package/internal/compiler-descriptors.js +54 -0
- package/internal/compiler-dynamic-cache.js +48 -0
- package/internal/compiler-entry.js +35 -0
- package/internal/compiler-generated-names.js +17 -0
- package/internal/compiler-intrinsics.js +50 -0
- package/internal/compiler-module-links.js +37 -0
- package/internal/compiler-operations.js +61 -0
- package/internal/compiler-platform-factory.js +84 -0
- package/internal/compiler-platform.js +136 -0
- package/internal/compiler-record-roles.js +53 -0
- package/internal/compiler-region-output.js +259 -0
- package/internal/compiler-resource-lowering.js +103 -0
- package/internal/compiler-scope-facts.js +115 -0
- package/internal/compiler-service.js +109 -0
- package/internal/compiler-source-cache.js +32 -0
- package/internal/compiler-source-pieces.js +93 -0
- package/internal/compiler-source-regions.js +132 -0
- package/internal/compiler-storage-source.js +54 -0
- package/internal/compiler-text.js +15 -0
- package/internal/compiler-typescript.cjs +2 -0
- package/internal/config-spec.js +83 -27
- package/internal/cordis-tools-owner.js +130 -21
- package/internal/diagnostic.js +27 -1
- package/internal/direct-surface-owner.js +76 -23
- package/internal/dynamic-binding-evidence.js +16 -0
- package/internal/dynamic-environment-compiler.js +779 -0
- package/internal/dynamic-environment-integration.js +91 -0
- package/internal/dynamic-environment-runtime.js +383 -0
- package/internal/dynamic-native-calls.js +153 -0
- package/internal/dynamic-native-runtime.js +262 -0
- package/internal/dynamic-scope-analysis.js +90 -0
- package/internal/edit-transport-owner.js +27 -2
- package/internal/execution-seam-compat.js +193 -0
- package/internal/failure-reporting.js +136 -28
- package/internal/host-rpc.js +66 -0
- package/internal/isolated-worker.js +555 -0
- package/internal/kernel-child.js +139 -0
- package/internal/kernel-worker.js +1179 -233
- package/internal/language-semantics.js +14 -0
- package/internal/legacy-binding-catalog.js +48 -0
- package/internal/legacy-cell-analysis.js +600 -0
- package/internal/legacy-cell-parser.js +50 -0
- package/internal/legacy-cell-rewriter.js +631 -0
- package/internal/legacy-repl-convenience.js +291 -0
- package/internal/managed-module-operations.js +170 -0
- package/internal/module-compilation.js +322 -0
- package/internal/module-runtime-platform.js +19 -0
- package/internal/module-transform-contract.js +42 -0
- package/internal/native-await-declarations.js +68 -0
- package/internal/native-root-compilation.js +54 -0
- package/internal/native-root-dynamic.js +67 -0
- package/internal/record-utils.js +24 -15
- package/internal/recovery-tips.js +27 -15
- package/internal/rejected-cell-editor.js +13 -8
- package/internal/repl-convenience.js +2 -289
- package/internal/repl-memory-projection.js +81 -12
- package/internal/repl-observation-interest.js +70 -0
- package/internal/repl-rewrite-contract.js +6 -0
- package/internal/repl-scope-normalizer.js +2091 -0
- package/internal/repl-value-observer.js +117 -0
- package/internal/rpc-contract.js +52 -0
- package/internal/runtime-bridge-owner.js +172 -28
- package/internal/runtime-config.js +48 -52
- package/internal/runtime-contexts.js +82 -10
- package/internal/runtime-intrinsics.js +101 -0
- package/internal/runtime-messages.js +111 -0
- package/internal/session-cell-executor.js +402 -87
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +123 -0
- package/internal/session-journal.js +199 -654
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +257 -95
- package/internal/session-state.js +247 -71
- package/internal/source-position-map.js +230 -71
- package/internal/stateful-module-compiler.js +154 -0
- package/internal/stateful-module-runtime.js +303 -0
- package/internal/stateful-root-compiler.js +600 -0
- package/internal/stateful-root-runtime.js +340 -0
- package/internal/typert-codec-compat.js +28 -0
- package/internal/typescript-transform.js +31 -0
- package/internal/user-binding-authoring.js +70 -0
- package/internal/user-binding-console-worker.js +244 -0
- package/internal/user-binding-console.js +148 -0
- package/internal/user-binding-draft-projection.js +335 -0
- package/internal/user-binding-model-context.js +31 -0
- package/internal/user-binding-runner.js +56 -0
- package/internal/user-bindings-owner.js +1065 -0
- package/internal/user-bindings-store.js +293 -0
- package/internal/user-bindings.js +361 -0
- package/internal/value-wire-schema.js +28 -0
- package/internal/value-wire.js +130 -91
- package/internal/worker-client.js +57 -67
- package/internal/worker-cwd-virtualization.js +80 -53
- package/internal/worker-environment.js +65 -0
- package/internal/worker-output-relay.js +29 -0
- package/internal/worker-repl-realm.js +134 -0
- package/internal/worker-shutdown.js +14 -0
- package/package.json +76 -7
- package/src/client-activity.js +95 -53
- package/src/client-authoring-view.js +580 -0
- package/src/client-binding-review.js +230 -0
- package/src/client-bindings-data.js +29 -0
- package/src/client-catalog.js +127 -0
- package/src/client-code-editor.js +84 -0
- package/src/client-console.js +112 -0
- package/src/client-copy.js +370 -0
- package/src/client-feature-gates.js +62 -0
- package/src/client-host-compat.js +150 -0
- package/src/client-indicator-view.js +267 -0
- package/src/client-repl-view.js +292 -0
- package/src/client-rpc.js +20 -0
- package/src/client-settings-view.js +221 -0
- package/src/client-styles.js +106 -0
- package/src/client-tool-view.js +108 -0
- package/src/client-transport.js +159 -0
- package/src/client-workbench.js +521 -0
- package/src/client.js +233 -615
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
5
|
-
|
|
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 {
|
|
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
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
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
|
|
209
|
+
function globalObjectMember(node) {
|
|
175
210
|
return node?.type === 'MemberExpression'
|
|
176
211
|
&& node.object?.type === 'Identifier'
|
|
177
|
-
&& node.object.name
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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(
|
|
302
|
+
walkAst(body, (node, parent, parentKey, { scopes, strict, thisIsGlobal }) => {
|
|
241
303
|
let nestedScopes = scopes
|
|
242
304
|
if (isFunction(node)) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
|| (
|
|
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
|
|
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],
|
|
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
|
|
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(
|
|
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(
|
|
304
|
-
if (node !==
|
|
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
|
|
307
|
-
const end = node.end
|
|
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
|
|
311
|
-
//
|
|
312
|
-
//
|
|
313
|
-
|
|
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
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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,
|
|
446
|
+
export function prepareProgram(program, options = {}) {
|
|
347
447
|
if (typeof program !== 'string') throw new TypeError('ptc-plus: program must be a string')
|
|
348
|
-
if (
|
|
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
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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
|
|
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
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
|
|
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
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
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
|
-
|
|
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
|
}
|