dsh-ptc-plus 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +66 -73
- package/README.md +66 -73
- 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 +30610 -722
- 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 +554 -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 +6 -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 +6 -4
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
- 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 +9 -3
- package/docs/adr/0014-persist-cell-rewrite-policy.md +11 -5
- 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 +8 -6
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +17 -3
- 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 +82 -22
- package/docs/binding-review-placement-design.md +200 -0
- package/docs/capability-projection.md +1 -1
- package/docs/client-ui.md +96 -20
- package/docs/durability-design.md +61 -24
- package/docs/evaluation.md +78 -6
- package/docs/installation.md +41 -6
- package/docs/program-data-plane.md +6 -0
- package/docs/publishing.md +5 -3
- package/docs/runtime-reference.md +79 -25
- package/docs/semantic-validation.md +29 -0
- package/docs/stateful-binding-updates-proposal.md +755 -0
- package/docs/user-bindings.en.md +64 -0
- package/docs/user-bindings.md +64 -0
- package/docs/value-wire.md +3 -3
- package/docs/verification.md +57 -0
- package/index.js +374 -92
- package/internal/ast-traversal.js +5 -2
- 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 +391 -0
- package/internal/binding-update-policy.js +66 -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 +252 -242
- 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 -553
- 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 +84 -0
- package/internal/compiler-module-links.js +34 -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 +91 -25
- 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 +87 -0
- package/internal/dynamic-environment-runtime.js +362 -0
- package/internal/dynamic-native-calls.js +150 -0
- package/internal/dynamic-native-runtime.js +248 -0
- package/internal/dynamic-scope-analysis.js +90 -0
- package/internal/edit-transport-owner.js +28 -3
- package/internal/execution-seam-compat.js +193 -0
- package/internal/failure-reporting.js +118 -18
- package/internal/host-rpc.js +66 -0
- package/internal/isolated-worker.js +548 -0
- package/internal/kernel-child.js +139 -0
- package/internal/kernel-worker.js +911 -116
- 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 +321 -0
- package/internal/module-runtime-platform.js +19 -0
- package/internal/module-transform-contract.js +12 -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/recovery-tips.js +27 -15
- package/internal/rejected-cell-editor.js +13 -8
- package/internal/repl-convenience.js +2 -201
- package/internal/repl-memory-projection.js +81 -12
- package/internal/repl-observation-interest.js +70 -0
- package/internal/repl-rewrite-contract.js +21 -0
- package/internal/repl-scope-normalizer.js +2091 -0
- package/internal/repl-value-observer.js +114 -0
- package/internal/rpc-contract.js +52 -0
- package/internal/runtime-bridge-owner.js +172 -28
- package/internal/runtime-config.js +48 -51
- package/internal/runtime-contexts.js +82 -10
- package/internal/runtime-messages.js +111 -0
- package/internal/session-cell-executor.js +455 -91
- package/internal/session-journal-recovery.js +684 -0
- package/internal/session-journal-schema.js +106 -0
- package/internal/session-journal.js +237 -440
- package/internal/session-log-view.js +42 -9
- package/internal/session-runtime.js +325 -80
- package/internal/session-state.js +249 -40
- package/internal/source-position-map.js +211 -71
- package/internal/stateful-module-compiler.js +154 -0
- package/internal/stateful-module-runtime.js +303 -0
- package/internal/stateful-root-compiler.js +598 -0
- package/internal/stateful-root-runtime.js +340 -0
- package/internal/typert-codec-compat.js +28 -0
- package/internal/typescript-transform.js +29 -0
- package/internal/user-binding-authoring.js +70 -0
- package/internal/user-binding-console-worker.js +184 -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 +353 -0
- package/internal/value-wire-schema.js +28 -0
- package/internal/value-wire.js +29 -20
- package/internal/worker-client.js +57 -67
- package/internal/worker-environment.js +45 -0
- package/internal/worker-output-relay.js +29 -0
- package/internal/worker-shutdown.js +14 -0
- package/package.json +81 -11
- package/src/client-activity.js +109 -45
- 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,10 +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'
|
|
5
|
+
import { parse as parseSource } from '@babel/parser'
|
|
6
|
+
import { parseExecutableCell } from './cell-parser.js'
|
|
7
|
+
import { redeclarationCommitTarget } from './repl-rewrite-contract.js'
|
|
8
8
|
import {
|
|
9
9
|
bindingNodes,
|
|
10
10
|
createGeneratedNameAllocator,
|
|
@@ -17,9 +17,15 @@ import {
|
|
|
17
17
|
renderDurabilityReason,
|
|
18
18
|
renderDurabilityReasons,
|
|
19
19
|
} from './module-policy.js'
|
|
20
|
-
import {
|
|
21
|
-
import { applySourceEdits, mapSourceSpan } from './source-position-map.js'
|
|
20
|
+
import { applySourceEdits, mapSourcePosition, mapSourceSpan } from './source-position-map.js'
|
|
22
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'
|
|
23
29
|
|
|
24
30
|
/**
|
|
25
31
|
* Pure AST analysis for PTC cells: binding inventory, durability classification,
|
|
@@ -27,35 +33,18 @@ import { SKIP_AST_CHILDREN, walkAst } from './ast-traversal.js'
|
|
|
27
33
|
* or session state so its behavior is fully testable in isolation.
|
|
28
34
|
*/
|
|
29
35
|
|
|
30
|
-
export function declarationSpan(node) {
|
|
31
|
-
const start = node.loc?.start
|
|
32
|
-
/* c8 ignore next */
|
|
33
|
-
const end = node.loc?.end ?? start
|
|
34
|
-
/* c8 ignore next */
|
|
35
|
-
if (start === undefined) return undefined
|
|
36
|
-
return {
|
|
37
|
-
line: Math.max(1, start.line - 1),
|
|
38
|
-
column: start.column + 1,
|
|
39
|
-
/* c8 ignore next */
|
|
40
|
-
...(end === undefined ? {} : {
|
|
41
|
-
end: {
|
|
42
|
-
line: Math.max(1, end.line - 1),
|
|
43
|
-
column: end.column + 1,
|
|
44
|
-
},
|
|
45
|
-
}),
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
36
|
|
|
49
37
|
function addPatternBindings(pattern, names) {
|
|
50
38
|
walkPattern(pattern, node => names.add(node.name))
|
|
51
39
|
}
|
|
52
40
|
|
|
53
|
-
function addPatternDeclarations(pattern, declarations, kind = 'variable', definitionSpan = undefined) {
|
|
41
|
+
function addPatternDeclarations(pattern, declarations, kind = 'variable', definitionSpan = undefined, writable = false) {
|
|
54
42
|
bindingNodes(pattern).forEach(node => declarations.push({
|
|
55
43
|
name: node.name,
|
|
56
44
|
kind,
|
|
57
45
|
span: declarationSpan(node),
|
|
58
46
|
definitionSpan,
|
|
47
|
+
writable,
|
|
59
48
|
}))
|
|
60
49
|
}
|
|
61
50
|
|
|
@@ -63,13 +52,35 @@ function topLevelBindings(body) {
|
|
|
63
52
|
return new Set(topLevelDeclarations(body).map(declaration => declaration.name))
|
|
64
53
|
}
|
|
65
54
|
|
|
66
|
-
function
|
|
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
|
+
|
|
69
|
+
function topLevelDeclarations(body, variableRedeclarations = false) {
|
|
67
70
|
const declarations = []
|
|
71
|
+
const seen = new Set()
|
|
68
72
|
for (const statement of body) {
|
|
69
73
|
if (statement.type === 'VariableDeclaration') {
|
|
74
|
+
seen.add(statement)
|
|
70
75
|
const definitionSpan = declarationSpan(statement)
|
|
71
76
|
for (const declaration of statement.declarations) {
|
|
72
|
-
addPatternDeclarations(
|
|
77
|
+
addPatternDeclarations(
|
|
78
|
+
declaration.id,
|
|
79
|
+
declarations,
|
|
80
|
+
'variable',
|
|
81
|
+
definitionSpan,
|
|
82
|
+
statement.kind !== 'const' || variableRedeclarations,
|
|
83
|
+
)
|
|
73
84
|
}
|
|
74
85
|
} else if ((statement.type === 'FunctionDeclaration' || statement.type === 'ClassDeclaration')
|
|
75
86
|
&& statement.id !== null) {
|
|
@@ -78,9 +89,12 @@ function topLevelDeclarations(body) {
|
|
|
78
89
|
kind: statement.type === 'ClassDeclaration' ? 'class' : 'function',
|
|
79
90
|
span: declarationSpan(statement.id),
|
|
80
91
|
definitionSpan: declarationSpan(statement),
|
|
92
|
+
commitDependency: redeclarationCommitTarget(statement.id.name, statement.start),
|
|
93
|
+
writable: true,
|
|
81
94
|
})
|
|
82
95
|
}
|
|
83
96
|
}
|
|
97
|
+
rootVarDeclarations(body, declarations, seen)
|
|
84
98
|
return declarations
|
|
85
99
|
}
|
|
86
100
|
|
|
@@ -97,21 +111,56 @@ function directBlockBindings(body) {
|
|
|
97
111
|
return names
|
|
98
112
|
}
|
|
99
113
|
|
|
100
|
-
function
|
|
114
|
+
function functionParameterBindings(node) {
|
|
101
115
|
const names = new Set()
|
|
102
116
|
if (node.id !== null && node.id !== undefined) names.add(node.id.name)
|
|
103
117
|
/* c8 ignore next */
|
|
104
118
|
for (const param of node.params ?? []) addPatternBindings(param, names)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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)
|
|
108
139
|
return SKIP_AST_CHILDREN
|
|
109
140
|
}
|
|
141
|
+
if (current.type === 'StaticBlock') return SKIP_AST_CHILDREN
|
|
110
142
|
if (current.type === 'VariableDeclaration' && current.kind === 'var') {
|
|
111
143
|
for (const declaration of current.declarations) addPatternBindings(declaration.id, names)
|
|
112
144
|
}
|
|
113
|
-
|
|
114
|
-
|
|
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())
|
|
115
164
|
}
|
|
116
165
|
|
|
117
166
|
function loopBindings(node) {
|
|
@@ -157,10 +206,10 @@ function staticMemberName(node) {
|
|
|
157
206
|
return undefined
|
|
158
207
|
}
|
|
159
208
|
|
|
160
|
-
function
|
|
209
|
+
function globalObjectMember(node) {
|
|
161
210
|
return node?.type === 'MemberExpression'
|
|
162
211
|
&& node.object?.type === 'Identifier'
|
|
163
|
-
&& node.object.name
|
|
212
|
+
&& ['global', 'globalThis'].includes(node.object.name)
|
|
164
213
|
? staticMemberName(node)
|
|
165
214
|
: undefined
|
|
166
215
|
}
|
|
@@ -171,12 +220,6 @@ function isFunction(node) {
|
|
|
171
220
|
|| node.type === 'ArrowFunctionExpression'
|
|
172
221
|
}
|
|
173
222
|
|
|
174
|
-
export class PreflightError extends Error {
|
|
175
|
-
constructor(message, node, span = undefined) {
|
|
176
|
-
super(message)
|
|
177
|
-
this.span = span ?? declarationSpan(node)
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
223
|
|
|
181
224
|
function staticModuleClassification(moduleLoads) {
|
|
182
225
|
const reasons = new Map()
|
|
@@ -197,15 +240,46 @@ function staticModuleClassification(moduleLoads) {
|
|
|
197
240
|
}
|
|
198
241
|
|
|
199
242
|
/** Conservatively classify a cell before giving it non-journalable capability. */
|
|
200
|
-
export function classifyDurability(code, knownBindings = new Set()) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
243
|
+
export function classifyDurability(code, knownBindings = new Set(), { sourceType = 'script', internalModules = new Set() } = {}) {
|
|
244
|
+
let body
|
|
245
|
+
let moduleLoads = []
|
|
246
|
+
if (sourceType === 'module') {
|
|
247
|
+
const program = parse(code, { ecmaVersion: 'latest', sourceType: 'module', locations: true })
|
|
248
|
+
knownBindings = new Set(knownBindings)
|
|
249
|
+
moduleLoads = program.body.filter(statement => statement.source != null
|
|
250
|
+
&& ['ImportDeclaration', 'ExportNamedDeclaration', 'ExportAllDeclaration'].includes(statement.type)
|
|
251
|
+
&& !internalModules.has(statement.source.value)).map(statement => ({
|
|
252
|
+
source: statement.source.value, position: declarationSpan(statement.source),
|
|
253
|
+
}))
|
|
254
|
+
body = { type: 'BlockStatement', body: program.body.flatMap(statement => {
|
|
255
|
+
if (statement.type === 'ImportDeclaration') {
|
|
256
|
+
for (const specifier of statement.specifiers) knownBindings.add(specifier.local.name)
|
|
257
|
+
return []
|
|
258
|
+
}
|
|
259
|
+
if (statement.type === 'ExportAllDeclaration') return []
|
|
260
|
+
if (statement.type === 'ExportNamedDeclaration') return statement.declaration === null ? [] : [statement.declaration]
|
|
261
|
+
if (statement.type === 'ExportDefaultDeclaration') return [statement.declaration]
|
|
262
|
+
return [statement]
|
|
263
|
+
}) }
|
|
264
|
+
} else ({ body } = parseExecutableCell(code))
|
|
265
|
+
const declared = topLevelBindings(body.body)
|
|
206
266
|
const rootBindings = new Set([...knownBindings, ...declared])
|
|
267
|
+
const rootStrict = sourceType === 'module' || hasStrictDirective(body)
|
|
268
|
+
addFunctionVariables(body, rootBindings, rootStrict)
|
|
269
|
+
// A `var` is instantiated with the cell even on the path that never runs its
|
|
270
|
+
// initializer, so it occupies the shared environment but does not by itself
|
|
271
|
+
// replace a name an earlier cell bound.
|
|
272
|
+
const hoistedVars = new Set()
|
|
273
|
+
walkAst(body, (node) => {
|
|
274
|
+
if (isFunction(node)) return SKIP_AST_CHILDREN
|
|
275
|
+
if (node.type === 'StaticBlock') return SKIP_AST_CHILDREN
|
|
276
|
+
if (node.type === 'VariableDeclaration' && node.kind === 'var') {
|
|
277
|
+
for (const declaration of node.declarations) addPatternBindings(declaration.id, hoistedVars)
|
|
278
|
+
}
|
|
279
|
+
})
|
|
207
280
|
const reasons = new Map()
|
|
208
281
|
const addReason = reason => reasons.set(renderDurabilityReason(reason), reason)
|
|
282
|
+
for (const reason of staticModuleClassification(moduleLoads)) addReason(reason)
|
|
209
283
|
const classifyModule = (source) => {
|
|
210
284
|
if (source?.type !== 'Literal' || typeof source.value !== 'string') {
|
|
211
285
|
addReason(DYNAMIC_MODULE_REASON)
|
|
@@ -223,12 +297,25 @@ export function classifyDurability(code, knownBindings = new Set()) {
|
|
|
223
297
|
}
|
|
224
298
|
return false
|
|
225
299
|
}
|
|
226
|
-
walkAst(
|
|
300
|
+
walkAst(body, (node, parent, parentKey, { scopes, strict }) => {
|
|
227
301
|
let nestedScopes = scopes
|
|
228
302
|
if (isFunction(node)) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
303
|
+
strict ||= hasStrictDirective(node.body)
|
|
304
|
+
nestedScopes = [...scopes, functionParameterBindings(node)]
|
|
305
|
+
} else if (node.type === 'BlockStatement' && node !== body) {
|
|
306
|
+
const names = directBlockBindings(node.body)
|
|
307
|
+
if (isFunction(parent)) addFunctionVariables(node, names, strict)
|
|
308
|
+
nestedScopes = [...scopes, names]
|
|
309
|
+
} else if (node.type === 'StaticBlock') {
|
|
310
|
+
const names = directBlockBindings(node.body)
|
|
311
|
+
for (const statement of node.body) addFunctionVariables(statement, names, true)
|
|
312
|
+
strict = true
|
|
313
|
+
nestedScopes = [...scopes, names]
|
|
314
|
+
} else if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {
|
|
315
|
+
strict = true
|
|
316
|
+
nestedScopes = [...scopes, new Set(node.id === null ? [] : [node.id.name])]
|
|
317
|
+
} else if (node.type === 'SwitchCase') {
|
|
318
|
+
nestedScopes = [...scopes, directBlockBindings(parent.cases.flatMap(branch => branch.consequent))]
|
|
232
319
|
} else if (node.type === 'CatchClause') {
|
|
233
320
|
const names = new Set()
|
|
234
321
|
addPatternBindings(node.param, names)
|
|
@@ -252,233 +339,156 @@ export function classifyDurability(code, knownBindings = new Set()) {
|
|
|
252
339
|
&& !isBound('process', nestedScopes) && node.name === 'process' && !isStableProcessMember(node, parent)) {
|
|
253
340
|
addReason(Object.freeze({ kind: 'ambient', name: 'process' }))
|
|
254
341
|
}
|
|
342
|
+
if (node.type === 'Identifier' && ['global', 'globalThis'].includes(node.name)
|
|
343
|
+
&& isReferenceIdentifier(node, parent, parentKey) && !isBound(node.name, nestedScopes)
|
|
344
|
+
&& !(parent?.type === 'MemberExpression' && parent.object === node)) {
|
|
345
|
+
addReason(Object.freeze({ kind: 'ambient', name: node.name }))
|
|
346
|
+
}
|
|
347
|
+
if (node.type === 'Identifier' && node.name === 'Math'
|
|
348
|
+
&& isReferenceIdentifier(node, parent, parentKey) && !isBound('Math', nestedScopes)
|
|
349
|
+
&& !(parent?.type === 'MemberExpression' && parent.object === node && staticMemberName(parent) !== undefined)) {
|
|
350
|
+
addReason(Object.freeze({ kind: 'ambient', name: 'Math' }))
|
|
351
|
+
}
|
|
255
352
|
if (node.type === 'MemberExpression'
|
|
256
353
|
&& ((node.object?.type === 'Identifier' && node.object.name === 'Math' && !isBound('Math', nestedScopes))
|
|
257
|
-
|| (
|
|
354
|
+
|| (globalObjectMember(node.object) === 'Math' && !isBound(node.object.object.name, nestedScopes)))
|
|
258
355
|
&& staticMemberName(node) === 'random') {
|
|
259
356
|
addReason(Object.freeze({ kind: 'math-random' }))
|
|
260
357
|
}
|
|
261
358
|
if (node.type === 'MemberExpression' && node.object?.type === 'Identifier'
|
|
262
|
-
&& node.object.name
|
|
359
|
+
&& ['global', 'globalThis'].includes(node.object.name) && !isBound(node.object.name, nestedScopes)) {
|
|
263
360
|
const member = staticMemberName(node)
|
|
264
361
|
if (member === undefined) addReason(Object.freeze({ kind: 'computed-global-access' }))
|
|
265
362
|
else if (member === 'process') addReason(Object.freeze({ kind: 'ambient', name: 'process' }))
|
|
266
363
|
else if (AMBIENT_GLOBALS.has(member)) addReason(Object.freeze({ kind: 'ambient', name: member }))
|
|
364
|
+
else if (member === 'global' || member === 'globalThis') addReason(Object.freeze({ kind: 'ambient', name: member }))
|
|
365
|
+
else if (member === 'Math' && !(parent?.type === 'MemberExpression' && parent.object === node
|
|
366
|
+
&& staticMemberName(parent) !== undefined)) {
|
|
367
|
+
addReason(Object.freeze({ kind: 'ambient', name: 'Math' }))
|
|
368
|
+
}
|
|
267
369
|
}
|
|
268
|
-
return nestedScopes
|
|
269
|
-
}, undefined, [rootBindings],
|
|
370
|
+
return { scopes: nestedScopes, strict }
|
|
371
|
+
}, undefined, { scopes: [rootBindings], strict: rootStrict })
|
|
270
372
|
return {
|
|
271
373
|
durability: reasons.size === 0 ? 'durable' : 'volatile',
|
|
272
374
|
reasons: Object.freeze([...reasons.values()]),
|
|
273
375
|
declared,
|
|
376
|
+
hoistedVars,
|
|
274
377
|
}
|
|
275
378
|
}
|
|
276
379
|
|
|
277
380
|
function rewriteCellReturns(code, sourceMap, unavailableNames) {
|
|
278
|
-
const
|
|
279
|
-
const tree = parse(wrapped, { ecmaVersion: 'latest', sourceType: 'script' })
|
|
280
|
-
const outer = tree.body[0]
|
|
281
|
-
/* c8 ignore next */
|
|
282
|
-
if (outer?.type !== 'FunctionDeclaration') throw new Error('ptc-plus: failed to parse cell wrapper')
|
|
283
|
-
const offset = STRIP_PREFIX.length
|
|
381
|
+
const { body } = parseExecutableCell(code)
|
|
284
382
|
const edits = []
|
|
285
|
-
const allocateName = createGeneratedNameAllocator(
|
|
383
|
+
const allocateName = createGeneratedNameAllocator(body, unavailableNames)
|
|
286
384
|
const returnSignal = allocateName('return_signal')
|
|
287
385
|
const signalReference = `this[${JSON.stringify(returnSignal)}]`
|
|
386
|
+
const completion = allocateName('cell_completion')
|
|
387
|
+
const exit = allocateName('cell_exit')
|
|
388
|
+
const ignored = allocateName('completion_effect')
|
|
389
|
+
let asyncCompletion = false
|
|
288
390
|
|
|
289
|
-
walkAst(
|
|
290
|
-
if (node !==
|
|
391
|
+
walkAst(body, (node) => {
|
|
392
|
+
if (node !== body && isFunction(node)) return SKIP_AST_CHILDREN
|
|
393
|
+
if (node.type === 'AwaitExpression' || node.await === true
|
|
394
|
+
|| node.type === 'VariableDeclaration' && node.kind === 'await using') asyncCompletion = true
|
|
291
395
|
if (node.type === 'ReturnStatement') {
|
|
292
|
-
const start = node.start
|
|
293
|
-
const end = node.end
|
|
396
|
+
const start = node.start
|
|
397
|
+
const end = node.end
|
|
294
398
|
const argument = node.argument === null
|
|
295
399
|
? ''
|
|
296
|
-
: code.slice(node.argument.start
|
|
297
|
-
//
|
|
298
|
-
//
|
|
299
|
-
|
|
300
|
-
edits.push({ start, end, text: `throw new ${signalReference}(${argument});` })
|
|
301
|
-
return SKIP_AST_CHILDREN
|
|
302
|
-
}
|
|
303
|
-
if (node.type === 'CatchClause') {
|
|
304
|
-
const bodyStart = node.body.start - offset + 1
|
|
305
|
-
const temporary = allocateName('caught')
|
|
306
|
-
if (node.param === null) {
|
|
307
|
-
edits.push({ start: node.start - offset + 5, end: node.start - offset + 5, text: ` (${temporary})` })
|
|
308
|
-
edits.push({ start: bodyStart, end: bodyStart, text: `\nif (${temporary} instanceof ${signalReference}) throw ${temporary};` })
|
|
309
|
-
} else if (node.param.type === 'Identifier') {
|
|
310
|
-
edits.push({
|
|
311
|
-
start: bodyStart,
|
|
312
|
-
end: bodyStart,
|
|
313
|
-
text: `\nif (${node.param.name} instanceof ${signalReference}) throw ${node.param.name};`,
|
|
314
|
-
})
|
|
315
|
-
} else {
|
|
316
|
-
const pattern = code.slice(node.param.start - offset, node.param.end - offset)
|
|
317
|
-
edits.push({ start: node.param.start - offset, end: node.param.end - offset, text: temporary })
|
|
318
|
-
edits.push({
|
|
319
|
-
start: bodyStart,
|
|
320
|
-
end: bodyStart,
|
|
321
|
-
text: `\nif (${temporary} instanceof ${signalReference}) throw ${temporary};\nconst ${pattern} = ${temporary};`,
|
|
322
|
-
})
|
|
323
|
-
}
|
|
400
|
+
: code.slice(node.argument.start, node.argument.end)
|
|
401
|
+
// Break leaves resource and finally scopes without making disposal
|
|
402
|
+
// suppress a private error for an otherwise successful return.
|
|
403
|
+
edits.push({ start, end, text: `{let ${ignored}=(${completion}=new ${signalReference}(${argument}));break ${exit};}` })
|
|
324
404
|
}
|
|
325
405
|
})
|
|
326
406
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
407
|
+
const directiveEnd = body.body.findLast(node => node.directive !== undefined)?.end ?? 0
|
|
408
|
+
// Fallthrough cancels a return overridden by finally break/continue. Empty
|
|
409
|
+
// declaration completions preserve the source's ordinary expression value.
|
|
410
|
+
edits.push({ start: directiveEnd, end: directiveEnd,
|
|
411
|
+
text: `\n{let ${completion};${exit}:{\n` })
|
|
412
|
+
edits.push({ start: code.length, end: code.length,
|
|
413
|
+
text: `\n;{let ${ignored}=(${completion}=void 0);}}{let ${ignored}=${completion}&&(()=>{throw ${completion}})();}}\n` })
|
|
414
|
+
let lowered = applySourceEdits(code, sourceMap, edits)
|
|
415
|
+
if (asyncCompletion) {
|
|
416
|
+
// The frame result is compiler-owned transport. Letting Node create it
|
|
417
|
+
// would hide the promise from our observer and re-enter source protocols
|
|
418
|
+
// when the host REPL awaits this realm's completion.
|
|
419
|
+
lowered = applySourceEdits(lowered.code, lowered.sourceMap, [
|
|
420
|
+
{ start: 0, end: 0, text: '(async()=>{' },
|
|
421
|
+
{ start: lowered.code.length, end: lowered.code.length, text: '\n})()' },
|
|
422
|
+
])
|
|
423
|
+
}
|
|
424
|
+
return { ...lowered, returnSignal, asyncCompletion }
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/** Workbench completion uses the same source grammar and compilation boundary. */
|
|
428
|
+
export function prepareConsoleProgram(source, options) {
|
|
429
|
+
const program = parseSource(source, { sourceType: 'script', errorRecovery: true,
|
|
430
|
+
allowImportExportEverywhere: true, allowUndeclaredExports: true,
|
|
431
|
+
allowAwaitOutsideFunction: true, allowReturnOutsideFunction: true, plugins: CELL_PARSER_PLUGINS }).program
|
|
432
|
+
const last = program.body.at(-1)
|
|
433
|
+
const input = last?.type !== 'ExpressionStatement' ? source
|
|
434
|
+
: `${source.slice(0, last.start)}return (${source.slice(last.expression.start, last.expression.end)});${source.slice(last.end)}`
|
|
435
|
+
return prepareProgram(input, options)
|
|
330
436
|
}
|
|
331
437
|
|
|
332
|
-
export function prepareProgram(program,
|
|
438
|
+
export function prepareProgram(program, options = {}) {
|
|
333
439
|
if (typeof program !== 'string') throw new TypeError('ptc-plus: program must be a string')
|
|
334
|
-
if (
|
|
335
|
-
|| typeof rewritesEnabled.autoRewriteImports !== 'boolean'
|
|
336
|
-
|| typeof rewritesEnabled.autoStripExports !== 'boolean'
|
|
337
|
-
|| typeof rewritesEnabled.autoSplitRedeclarations !== 'boolean') {
|
|
338
|
-
throw new TypeError('ptc-plus: rewrite policy must define autoRewriteImports, autoStripExports, and autoSplitRedeclarations booleans')
|
|
339
|
-
}
|
|
340
|
-
const unavailableGeneratedNames = new Set([
|
|
341
|
-
...knownBindings,
|
|
342
|
-
...reservedBindings,
|
|
343
|
-
...importBindings.keys(),
|
|
344
|
-
...importNamespaces,
|
|
345
|
-
])
|
|
346
|
-
const moduleRewrite = rewriteModuleImportsExports(
|
|
347
|
-
program,
|
|
348
|
-
rewritesEnabled,
|
|
349
|
-
importBindings,
|
|
350
|
-
importNamespaces,
|
|
351
|
-
unavailableGeneratedNames,
|
|
352
|
-
)
|
|
353
|
-
const staticModuleReasons = staticModuleClassification(moduleRewrite.moduleLoads)
|
|
354
|
-
const wrapped = STRIP_PREFIX + moduleRewrite.code + STRIP_SUFFIX
|
|
355
|
-
let stripped = wrapped
|
|
356
|
-
let tree
|
|
357
|
-
try {
|
|
358
|
-
tree = parse(wrapped, { ecmaVersion: 'latest', sourceType: 'script', locations: true })
|
|
359
|
-
} catch (javascriptError) {
|
|
440
|
+
if (options.languageSemantics === undefined || options.languageSemantics === 'legacy-v1') {
|
|
360
441
|
try {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const code = stripped.slice(STRIP_PREFIX.length, stripped.length - STRIP_SUFFIX.length)
|
|
368
|
-
const sourceMap = moduleRewrite.sourceMap
|
|
369
|
-
const outer = tree.body[0]
|
|
370
|
-
/* c8 ignore next */
|
|
371
|
-
const generatedDeclarations = outer?.type === 'FunctionDeclaration' ? topLevelDeclarations(outer.body.body) : []
|
|
372
|
-
const collisionFor = (declaration) => {
|
|
373
|
-
/* c8 ignore next */
|
|
374
|
-
const mapped = declaration.original === true ? declaration.span : declaration.span === undefined
|
|
375
|
-
? { line: 1, column: 1 }
|
|
376
|
-
: mapSourceSpan(declaration.span, code, program, sourceMap)
|
|
377
|
-
return {
|
|
378
|
-
name: declaration.name,
|
|
379
|
-
start: { line: mapped.line, column: mapped.column },
|
|
380
|
-
/* c8 ignore next */
|
|
381
|
-
...(mapped.end === undefined ? {} : { end: mapped.end }),
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
const classifyPrepared = (preparedCode, preparedSourceMap) => {
|
|
385
|
-
try {
|
|
386
|
-
const classification = classifyDurability(preparedCode, knownBindings)
|
|
387
|
-
const reasons = new Map()
|
|
388
|
-
for (const reason of [...staticModuleReasons, ...classification.reasons]) {
|
|
389
|
-
reasons.set(renderDurabilityReason(reason), reason)
|
|
390
|
-
}
|
|
391
|
-
return {
|
|
392
|
-
...classification,
|
|
393
|
-
durability: reasons.size === 0 ? 'durable' : 'volatile',
|
|
394
|
-
reasons: Object.freeze([...reasons.values()]),
|
|
395
|
-
reason: renderDurabilityReasons([...reasons.values()]),
|
|
396
|
-
}
|
|
442
|
+
// Logical imports have no persistent native namespace slot. Their proved
|
|
443
|
+
// identity enters the native execution environment with the other roots.
|
|
444
|
+
const nativeOptions = { ...options, importBindings: new Map([...options.importBindings ?? []]
|
|
445
|
+
.filter(([name]) => !options.establishedRoots?.has(name) || options.nativeBindings?.has(name))) }
|
|
446
|
+
const prepared = adaptNativeRootDynamic(adaptLegacyModuleImports(prepareLegacyProgram(program, nativeOptions), nativeOptions), options, program)
|
|
447
|
+
return { ...prepared, sourceRegions: sourceRegionData(prepared.sourceRegions), languageSemantics: 'legacy-v1' }
|
|
397
448
|
} catch (error) {
|
|
398
|
-
if (error instanceof PreflightError
|
|
399
|
-
error.span = mapSourceSpan(error.span, preparedCode, program, preparedSourceMap)
|
|
400
|
-
}
|
|
449
|
+
if (error instanceof LegacyPreflightError) throw new PreflightError(error.message, undefined, error.span)
|
|
401
450
|
throw error
|
|
402
451
|
}
|
|
403
452
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
return {
|
|
425
|
-
...classification,
|
|
426
|
-
imports,
|
|
427
|
-
declared: new Set([...classification.declared, ...importedNames]),
|
|
453
|
+
if (options.languageSemantics === 'stateful-v1' || options.languageSemantics === 'protected-v1') {
|
|
454
|
+
let normalized
|
|
455
|
+
let prepared
|
|
456
|
+
let callableSources
|
|
457
|
+
const intrinsicContext = { bindings: new Set() }
|
|
458
|
+
try {
|
|
459
|
+
const marked = markCallableSources(program, undefined, { plugins: CELL_PARSER_PLUGINS, allowImportExportEverywhere: true, allowUndeclaredExports: true },
|
|
460
|
+
{ lowerNativeSource: lowerNativeLanguageSource, nativeUsing: options.nativeUsing })
|
|
461
|
+
callableSources = marked.callableSources
|
|
462
|
+
normalized = normalizeStatefulScopes(marked.code, marked.sourceMap, { mode: options.languageSemantics,
|
|
463
|
+
nativeJavaScript: marked.nativeJavaScript, deferDecorators: true, deferResources: true, intrinsicContext })
|
|
464
|
+
prepared = compileStatefulRoot(normalized.code, { ...options, sourceMap: normalized.sourceMap,
|
|
465
|
+
internalBindings: normalized.internalBindings, dynamicBindings: normalized.dynamicBindings,
|
|
466
|
+
privateBindings: normalized.privateBindings, originalSource: program })
|
|
467
|
+
} catch (error) {
|
|
468
|
+
if (error instanceof ModuleRewriteError) throw error
|
|
469
|
+
const position = error.loc === undefined ? undefined : { line: error.loc.line, column: error.loc.column + 1 }
|
|
470
|
+
throw new ModuleRewriteError(error.message, normalized === undefined ? position
|
|
471
|
+
: mapSourcePosition(position, normalized.code, program, normalized.sourceMap))
|
|
428
472
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
...
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
473
|
+
prepared = { ...prepared, deferredHelpers: normalized.deferredHelpers }
|
|
474
|
+
intrinsicContext.expression = `this[${JSON.stringify(prepared.rootRuntimeName)}].intrinsics`
|
|
475
|
+
const classificationSource = bindCompilerIntrinsics(lowerStatefulDecorators(
|
|
476
|
+
{ ...prepared, code: prepared.classificationCode }, undefined, intrinsicContext), intrinsicContext).code
|
|
477
|
+
prepared = bindCompilerIntrinsics(lowerStatefulDecorators(prepared, undefined, intrinsicContext), intrinsicContext)
|
|
478
|
+
prepared = lowerStatefulResources(prepared, { intrinsicContext, nativeUsing: options.nativeUsing })
|
|
479
|
+
const parsed = parseExecutableCell(prepared.code, { eraseTypes: true })
|
|
480
|
+
const classification = classifyDurability(parseExecutableCell(classificationSource, { eraseTypes: true }).code,
|
|
481
|
+
new Set([...(options.knownBindings ?? []), ...prepared.declared]))
|
|
482
|
+
const reasons = [...staticModuleClassification(prepared.moduleLoads), ...classification.reasons]
|
|
483
|
+
const lowered = rewriteCellReturns(parsed.code, prepared.sourceMap,
|
|
484
|
+
new Set([...prepared.declared, ...(options.knownBindings ?? [])]))
|
|
485
|
+
prepared.rootBindings.callableSources = collectCallableSources(lowered.code, callableSources)
|
|
486
|
+
return { ...prepared, ...lowered,
|
|
487
|
+
sourceRegions: sourceRegionData(prepared.sourceRegions),
|
|
488
|
+
returnSignal: lowered.returnSignal,
|
|
489
|
+
durability: reasons.length === 0 ? 'durable' : 'volatile', reasons: Object.freeze(reasons),
|
|
490
|
+
reason: renderDurabilityReasons(reasons),
|
|
445
491
|
}
|
|
446
492
|
}
|
|
447
|
-
|
|
448
|
-
code,
|
|
449
|
-
sourceMap,
|
|
450
|
-
body: looseTopLevelRedeclarations && outer?.type === 'FunctionDeclaration' ? outer.body.body : undefined,
|
|
451
|
-
offset: STRIP_PREFIX.length,
|
|
452
|
-
knownBindings: new Set([...knownBindings].filter(name => !importBindings.has(name))),
|
|
453
|
-
declarations,
|
|
454
|
-
declarationSpan,
|
|
455
|
-
collisionFor,
|
|
456
|
-
autoSplitRedeclarations: rewritesEnabled.autoSplitRedeclarations,
|
|
457
|
-
})
|
|
458
|
-
const { executableCode, executableSourceMap, collisions, redeclared, rewrites } = convenience
|
|
459
|
-
// Classification sees the rewritten program so declared bindings reflect the
|
|
460
|
-
// split form; it must never see the return rewrite, whose computed
|
|
461
|
-
// globalThis access would mark every returning cell volatile.
|
|
462
|
-
const classification = normalizeClassification(classifyPrepared(executableCode, executableSourceMap))
|
|
463
|
-
let lowered = { code, sourceMap }
|
|
464
|
-
if (collisions.length === 0) {
|
|
465
|
-
lowered = rewriteCellReturns(
|
|
466
|
-
executableCode,
|
|
467
|
-
executableSourceMap,
|
|
468
|
-
unavailableGeneratedNames,
|
|
469
|
-
)
|
|
470
|
-
}
|
|
471
|
-
return {
|
|
472
|
-
code: lowered.code,
|
|
473
|
-
sourceMap: lowered.sourceMap,
|
|
474
|
-
...(lowered.returnSignal === undefined ? {} : { returnSignal: lowered.returnSignal }),
|
|
475
|
-
...classification,
|
|
476
|
-
declarations,
|
|
477
|
-
imports: classification.imports,
|
|
478
|
-
importNamespaces: moduleRewrite.importNamespaces,
|
|
479
|
-
collisions,
|
|
480
|
-
redeclared,
|
|
481
|
-
rewrites: [...moduleRewrite.rewrites, ...rewrites],
|
|
482
|
-
moduleLoads: moduleRewrite.moduleLoads,
|
|
483
|
-
}
|
|
493
|
+
throw new TypeError('ptc-plus: unsupported language semantics')
|
|
484
494
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { captureCompilerIntrinsics } from './compiler-intrinsics.js'
|
|
2
|
+
|
|
3
|
+
/** Execution owns its frame promise; the returned source value still uses
|
|
4
|
+
* Await in the source realm. Neither consumer performs host-realm assimilation
|
|
5
|
+
* of an unexamined source promise. */
|
|
6
|
+
export function createCellCompletionObserver(realmFunction) {
|
|
7
|
+
const intrinsics = captureCompilerIntrinsics(realmFunction)
|
|
8
|
+
return {
|
|
9
|
+
observe: intrinsics.observeOwnedPromise,
|
|
10
|
+
settle(value, fulfilled, rejected) {
|
|
11
|
+
const completion = intrinsics.awaitValue(value, value => ({ value }))
|
|
12
|
+
intrinsics.observeOwnedPromise(completion, result => fulfilled(result.value), rejected)
|
|
13
|
+
},
|
|
14
|
+
}
|
|
15
|
+
}
|