@scriptc/compiler 0.2.1 → 0.2.3
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/ambient/scriptc-node-fallback.d.ts +158 -31
- package/dist/backend/cycle-analysis.js +63 -50
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +51 -0
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/llvm/borrowed-receivers.d.ts +9 -0
- package/dist/backend/llvm/borrowed-receivers.js +58 -0
- package/dist/backend/llvm/borrowed-receivers.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.d.ts +20 -0
- package/dist/backend/llvm/call-lifetimes.js +179 -0
- package/dist/backend/llvm/call-lifetimes.js.map +1 -0
- package/dist/backend/llvm/call-lifetimes.test.d.ts +1 -0
- package/dist/backend/llvm/call-lifetimes.test.js +205 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +5 -2
- package/dist/backend/llvm/dyn.js +163 -47
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +37 -1
- package/dist/backend/llvm/emitter.js +209 -21
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +29 -2
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +1 -1
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-calls.js +42 -5
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +75 -13
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +31 -6
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +6 -5
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +1 -1
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +75 -19
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
- package/dist/backend/llvm/expr-stream-callbacks.js +7 -57
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +41 -3
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +12 -9
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +70 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +44 -0
- package/dist/backend/llvm/local-array-reads.js +313 -0
- package/dist/backend/llvm/local-array-reads.js.map +1 -0
- package/dist/backend/llvm/local-array-reads.test.d.ts +1 -0
- package/dist/backend/llvm/local-array-reads.test.js +446 -0
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.d.ts +36 -0
- package/dist/backend/llvm/map-read-lifetimes.js +128 -0
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.test.d.ts +1 -0
- package/dist/backend/llvm/map-read-lifetimes.test.js +123 -0
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -0
- package/dist/backend/llvm/shapes.js +1 -0
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/split.js +15 -5
- package/dist/backend/llvm/split.js.map +1 -1
- package/dist/backend/llvm/split.test.js +17 -0
- package/dist/backend/llvm/split.test.js.map +1 -1
- package/dist/backend/llvm/stack-unions.d.ts +20 -0
- package/dist/backend/llvm/stack-unions.js +61 -0
- package/dist/backend/llvm/stack-unions.js.map +1 -0
- package/dist/backend/llvm/stack-unions.test.d.ts +1 -0
- package/dist/backend/llvm/stack-unions.test.js +241 -0
- package/dist/backend/llvm/stack-unions.test.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.d.ts +12 -0
- package/dist/backend/llvm/string-lifetimes.js +70 -0
- package/dist/backend/llvm/string-lifetimes.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.test.d.ts +1 -0
- package/dist/backend/llvm/string-lifetimes.test.js +230 -0
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -0
- package/dist/backend/mangle.d.ts +2 -0
- package/dist/backend/mangle.js +4 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.js +71 -29
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +104 -1
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +1 -1
- package/dist/backend/native-codegen.js +4 -3
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +11 -0
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +2 -2
- package/dist/backend/native-toolchain.js +2 -0
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/target-diagnostics.d.ts +5 -0
- package/dist/backend/target-diagnostics.js +72 -1
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.d.ts +1 -0
- package/dist/backend/target-diagnostics.test.js +68 -0
- package/dist/backend/target-diagnostics.test.js.map +1 -0
- package/dist/coverage/surface-manifest.js +5 -3
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +7 -3
- package/dist/executable/executable-cache.js +47 -11
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +109 -2
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.js +2 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/builtin-modules.d.ts +1 -1
- package/dist/frontend/builtin-modules.js +1 -1
- package/dist/frontend/builtin-modules.js.map +1 -1
- package/dist/frontend/function-completion.d.ts +6 -0
- package/dist/frontend/function-completion.js +50 -0
- package/dist/frontend/function-completion.js.map +1 -0
- package/dist/frontend/input-tracker.js +3 -3
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/input-tracker.test.js +38 -2
- package/dist/frontend/input-tracker.test.js.map +1 -1
- package/dist/frontend/lowering/abstract-equality.js +5 -1
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/checked-iterable-spread.d.ts +4 -0
- package/dist/frontend/lowering/checked-iterable-spread.js +30 -0
- package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -0
- package/dist/frontend/lowering/checked-promise-all.d.ts +5 -0
- package/dist/frontend/lowering/checked-promise-all.js +31 -0
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -0
- package/dist/frontend/lowering/class-callbacks.d.ts +1 -1
- package/dist/frontend/lowering/class-callbacks.js +7 -6
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +2 -0
- package/dist/frontend/lowering/class-construction.js +34 -5
- package/dist/frontend/lowering/class-construction.js.map +1 -1
- package/dist/frontend/lowering/class-descriptors.d.ts +1 -1
- package/dist/frontend/lowering/class-descriptors.js +12 -5
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +25 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +597 -78
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +64 -2
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.d.ts +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +11 -41
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.d.ts +16 -0
- package/dist/frontend/lowering/class-method-values.js +60 -29
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +5 -1
- package/dist/frontend/lowering/class-prototypes.js +69 -10
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +4 -4
- package/dist/frontend/lowering/class-runtime-statics.js +26 -8
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
- package/dist/frontend/lowering/class-static-data.d.ts +1 -0
- package/dist/frontend/lowering/class-static-data.js +4 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/collection-ingestion.d.ts +31 -0
- package/dist/frontend/lowering/collection-ingestion.js +215 -0
- package/dist/frontend/lowering/collection-ingestion.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.js +19 -4
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +6 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.d.ts +13 -0
- package/dist/frontend/lowering/deferred-module-initializers.js +410 -0
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -0
- package/dist/frontend/lowering/deferred-module-initializers.test.d.ts +1 -0
- package/dist/frontend/lowering/deferred-module-initializers.test.js +92 -0
- package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -0
- package/dist/frontend/lowering/expressions/object-literals.js +31 -1
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.js +3 -3
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/import-meta.d.ts +10 -0
- package/dist/frontend/lowering/import-meta.js +52 -0
- package/dist/frontend/lowering/import-meta.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.js +105 -41
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +2 -0
- package/dist/frontend/lowering/lower-builtin-values.js +22 -1
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +7 -22
- package/dist/frontend/lowering/lower-builtins.js +439 -95
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +289 -76
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +5 -0
- package/dist/frontend/lowering/lower-classes.js +443 -29
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +6 -2
- package/dist/frontend/lowering/lower-containers.js +79 -20
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +10 -6
- package/dist/frontend/lowering/lower-exprs.js +329 -170
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +5 -1
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +58 -1
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +4 -0
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-island.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-island.test.js +51 -0
- package/dist/frontend/lowering/lower-island.test.js.map +1 -0
- package/dist/frontend/lowering/lower-modules.d.ts +1 -3
- package/dist/frontend/lowering/lower-modules.js +186 -82
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.js +69 -1
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +172 -103
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-stmts.test.js +77 -0
- package/dist/frontend/lowering/lower-stmts.test.js.map +1 -0
- package/dist/frontend/lowering/lower-stream.js +2 -0
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-system-errors.d.ts +6 -0
- package/dist/frontend/lowering/lower-system-errors.js +29 -0
- package/dist/frontend/lowering/lower-system-errors.js.map +1 -0
- package/dist/frontend/lowering/lower-url.d.ts +2 -1
- package/dist/frontend/lowering/lower-url.js +32 -9
- package/dist/frontend/lowering/lower-url.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +30 -12
- package/dist/frontend/lowering/lowerer.js +268 -49
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +38 -0
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/module-namespace-elements.d.ts +7 -0
- package/dist/frontend/lowering/module-namespace-elements.js +54 -0
- package/dist/frontend/lowering/module-namespace-elements.js.map +1 -0
- package/dist/frontend/lowering/object-factory-new.d.ts +4 -3
- package/dist/frontend/lowering/object-factory-new.js +27 -14
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +3 -2
- package/dist/frontend/lowering/surfaces.js +93 -33
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.js +3 -0
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.test.js +2 -1
- package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -1
- package/dist/frontend/module-syntax.d.ts +1 -1
- package/dist/frontend/module-syntax.js +8 -1
- package/dist/frontend/module-syntax.js.map +1 -1
- package/dist/frontend/module-syntax.test.js +10 -0
- package/dist/frontend/module-syntax.test.js.map +1 -1
- package/dist/frontend/npm.d.ts +4 -0
- package/dist/frontend/npm.js +86 -33
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +103 -0
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/pipeline-native.js +2 -1
- package/dist/frontend/pipeline-native.js.map +1 -1
- package/dist/frontend/program.js +4 -2
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/services-node.js +3 -2
- package/dist/frontend/services-node.js.map +1 -1
- package/dist/frontend/services.d.ts +5 -1
- package/dist/frontend/services.js +9 -1
- package/dist/frontend/services.js.map +1 -1
- package/dist/frontend/services.test.js +21 -0
- package/dist/frontend/services.test.js.map +1 -1
- package/dist/frontend/ts7/ast-node.d.ts +2 -0
- package/dist/frontend/ts7/ast-node.js +30 -4
- package/dist/frontend/ts7/ast-node.js.map +1 -1
- package/dist/frontend/ts7/ast-node.test.js +60 -1
- package/dist/frontend/ts7/ast-node.test.js.map +1 -1
- package/dist/frontend/type-mapper.js +89 -14
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/union-discriminants.js +22 -7
- package/dist/frontend/union-discriminants.js.map +1 -1
- package/dist/index.js +19 -12
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.js +1 -0
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +7 -0
- package/dist/ir/integer-loops.js +23 -0
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/integer-loops.test.d.ts +1 -0
- package/dist/ir/integer-loops.test.js +41 -0
- package/dist/ir/integer-loops.test.js.map +1 -0
- package/dist/ir/ir.d.ts +44 -26
- package/dist/ir/ir.js +69 -11
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +18 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/serialize.js +21 -1
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +21 -0
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/traverse.d.ts +0 -3
- package/dist/ir/traverse.js +33 -20
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +216 -80
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +244 -1
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/compiler-self-identity.js +1 -1
- package/dist/library/compiler-self-identity.test.js +2 -2
- package/dist/library/compiler-self-identity.test.js.map +1 -1
- package/dist/library/fence-eval.js +9 -2
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/fence-eval.test.d.ts +1 -0
- package/dist/library/fence-eval.test.js +21 -0
- package/dist/library/fence-eval.test.js.map +1 -0
- package/dist/library/int-infer.d.ts +2 -2
- package/dist/library/int-infer.js +10 -7
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +44 -0
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/prepare.js +2 -1
- package/dist/library/prepare.js.map +1 -1
- package/dist/native/runtime-typescript.d.ts +4 -0
- package/dist/native/runtime-typescript.js +61 -0
- package/dist/native/runtime-typescript.js.map +1 -0
- package/dist/native/runtime-typescript.test.d.ts +1 -0
- package/dist/native/runtime-typescript.test.js +41 -0
- package/dist/native/runtime-typescript.test.js.map +1 -0
- package/package.json +20 -20
- package/surface-manifest.json +385 -29
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { pathModuleValue } from "./lower-builtin-values.js";
|
|
2
|
-
import { everyExprChild, everyStmtChild } from "../../ir/traverse.js";
|
|
1
|
+
import { lowerUtilTypeValue, pathModuleValue, utilTypesModuleValue } from "./lower-builtin-values.js";
|
|
2
|
+
import { everyExprChild, everyStmtChild, transformStmtList } from "../../ir/traverse.js";
|
|
3
3
|
import { RuntimeOptionalLocals } from "./runtime-optional-locals.js";
|
|
4
4
|
import { sanitizeUnregisteredClassTypes } from "./sanitize-class-types.js";
|
|
5
5
|
import { UnregisteredClassTypes } from "./unregistered-class-types.js";
|
|
@@ -9,7 +9,8 @@ import { bindingInContext, captureContextBinding, declareContextLocal, declareCo
|
|
|
9
9
|
export { newFnCtx } from "./function-context.js";
|
|
10
10
|
import { InternalCompilerError } from "../../errors.js";
|
|
11
11
|
import { defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "./optional-arguments.js";
|
|
12
|
-
import { ClassDynamicDispatch } from "./class-dynamic-dispatch.js";
|
|
12
|
+
import { ClassDynamicDispatch, trackClassFieldCreation } from "./class-dynamic-dispatch.js";
|
|
13
|
+
import { DeferredModuleInitializers } from "./deferred-module-initializers.js";
|
|
13
14
|
import { finalizeClassMethodValues } from "./class-method-values.js";
|
|
14
15
|
/* AST + checker → IR.
|
|
15
16
|
*
|
|
@@ -37,7 +38,7 @@ import {} from "../npm.js";
|
|
|
37
38
|
import { provenanceActive } from "../provenance-registry.js";
|
|
38
39
|
import { ambientDtsPath, canonicalBuiltinModule, cjsExportAssignmentOf, cjsExportDiscardReason, fallbackDtsPath, isCjsExportTableLiteral, isCjsJsFile, isJsSourceFile, isNodeEsmFile, isNodeTypesPath, locOf, orderedImportsOf, overridesDtsPath, npmStaticDepSf7, requireSpecOf, resolveImport, workspacePackageOfPath, } from "../program.js";
|
|
39
40
|
import { containsRecord, containsUnion, describeComponentBlocker, describeRecordMemberBlocker, formatIrType, ISLAND_AMBIENT_TYPES, isUnitOnlyTsType, jsOpenObjectType, mapType, ShapeRegistry, typeKey, UnionRegistry, withUndefinedArm as withUndefinedArmCanonical, } from "../type-mapper.js";
|
|
40
|
-
import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
|
|
41
|
+
import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtinModuleConstOf, builtinModulesArrayLit, builtinFenceHintOf, builtinModuleFnOf, stdlibMemberFence, isStdlibMember, isStdlibSymbol, isStdlibGlobal, stdlibGlobalNameOf, stdlibGlobalMember, nodeTypesOnlySymbol } from "./surfaces.js";
|
|
41
42
|
import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules, appendForkModules } from "./lower-modules.js";
|
|
42
43
|
import { prepareCjsModuleGraph } from "./lower-node-module.js";
|
|
43
44
|
import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, findGenericMethodOn, findGenericStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorConstructorArgs, lowerNew, accessorCall } from "./lower-classes.js";
|
|
@@ -57,8 +58,9 @@ import { lowerDgramDnsModuleCall, lowerDgramMethodCall } from "./lower-dgram.js"
|
|
|
57
58
|
import { lowerNodeTestModuleCall, lowerTestDirectCall, lowerTestMethodCall, lowerTestCtxProperty } from "./lower-test.js";
|
|
58
59
|
import { lowerAssertModuleCall, lowerAssertDirectCall } from "./lower-assert.js";
|
|
59
60
|
import { lowerUtilModuleCall } from "./lower-inspect.js";
|
|
61
|
+
import { lowerSystemErrorMapValue } from "./lower-system-errors.js";
|
|
60
62
|
import { lowerComptime, comptimeBakeable, rejectComptimeCaptures, comptimeValueToIr } from "./lower-comptime.js";
|
|
61
|
-
import { lowerStmts, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, lowerJsvalBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement } from "./lower-stmts.js";
|
|
63
|
+
import { lowerStmts, hasJsTypeAnnotation, noteBlockedBindings, isBlockedBinding, lowerScopedBlock, predeclareForwardCapture, predeclareForwardFnDecl, predeclareForwardVar, lowerStmt, lowerVarStatement, lowerDestructuringDecl, lowerDestructuringAssignParts, lowerBindingPattern, lowerJsvalBindingPattern, checkBindingElement, bindPatternTarget, isParseArgsDynCheckerType, lowerVarDeclList, lowerVarDecl, lowerSwitch, lowerTry, lowerExprStatement, lowerForOf, lowerForStatement } from "./lower-stmts.js";
|
|
62
64
|
import { lowerExpr, maybeNarrow, lowerUnitComparison, lowerNullishCoalesce, lowerCondition, ensureBool, requireTruthyUnion, eqComparableUnion, lowerIntrinsicProperty, lowerArrayLiteral, lowerElementAccess, lowerElementWrite, lowerRecordKeyRead, ensureString, lowerTemplate, lowerAsExpression, lowerPrefixUnary, lowerBinary, lowerCaughtTypeofTest, caughtRead, caughtLocalOf, caughtToString, lowerInstanceOf, lowerRegexLiteral, lowerFieldRead, lowerUnionProperty, fieldTarget, fieldGetExpr, fieldSetStmt, lowerFieldCompound, uniqueSymbolKeyOf } from "./lower-exprs.js";
|
|
63
65
|
import { finishOptionalChain, isOptionalChainTail, lowerOptionalChain } from "./expressions/optional-chains.js";
|
|
64
66
|
import { foldedStringKeyOf, lowerDynObjectLiteral, lowerObjectLiteral, lowerShorthandValue, rejectThisInObjectMethod } from "./expressions/object-literals.js";
|
|
@@ -751,18 +753,34 @@ function anyPiecedFuncType(lowerer, node, t) {
|
|
|
751
753
|
return null;
|
|
752
754
|
return { kind: "func", params, ret };
|
|
753
755
|
}
|
|
754
|
-
/** The
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
* REFERENCE-SITE approximation of JS's creation-site naming — an aliased
|
|
758
|
-
* binding reports the alias; SEMANTICS.md), named function expressions
|
|
756
|
+
/** The JS `Function.prototype.name` of an expression flowing into a dyn
|
|
757
|
+
* slot. Immutable identifier aliases retain their creation-site name; property
|
|
758
|
+
* reads answer the referenced name. Named function expressions
|
|
759
759
|
* their own name, anonymous function/arrow expressions their
|
|
760
760
|
* NamedEvaluation home (a variable initializer or property assignment).
|
|
761
761
|
* Null when nothing names the value (the box stays anonymous). */
|
|
762
|
-
export function jsFuncNameOf(node) {
|
|
762
|
+
export function jsFuncNameOf(node, lowerer) {
|
|
763
763
|
let n = node;
|
|
764
764
|
while (ts.isParenthesizedExpression(n))
|
|
765
765
|
n = n.expression;
|
|
766
|
+
const seen = new Set();
|
|
767
|
+
while (lowerer && ts.isIdentifier(n)) {
|
|
768
|
+
const symbol = lowerer.resolveValueSymbol(n);
|
|
769
|
+
if (!symbol || seen.has(symbol))
|
|
770
|
+
break;
|
|
771
|
+
seen.add(symbol);
|
|
772
|
+
const declaration = lowerer.checker.valueDeclarationOf(symbol);
|
|
773
|
+
if (declaration && ts.isFunctionDeclaration(declaration)) {
|
|
774
|
+
n = declaration;
|
|
775
|
+
break;
|
|
776
|
+
}
|
|
777
|
+
if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer ||
|
|
778
|
+
(ts.getCombinedNodeFlags(declaration) & ts.NodeFlags.Const) === 0)
|
|
779
|
+
break;
|
|
780
|
+
n = declaration.initializer;
|
|
781
|
+
while (ts.isParenthesizedExpression(n))
|
|
782
|
+
n = n.expression;
|
|
783
|
+
}
|
|
766
784
|
if (ts.isIdentifier(n))
|
|
767
785
|
return n.text;
|
|
768
786
|
if (ts.isPropertyAccessExpression(n))
|
|
@@ -811,6 +829,9 @@ export class Lowerer {
|
|
|
811
829
|
/** Per-symbol result of the never-reassigned file scan
|
|
812
830
|
* (bindingNeverReassigned — object-literal generic-method receivers). */
|
|
813
831
|
neverReassignedCache = new Map();
|
|
832
|
+
/** Syntactic writes indexed once per JS scope. Symbol and RHS type
|
|
833
|
+
* checks remain contextual to each binding probe. */
|
|
834
|
+
jsBindingWritesByOwner = new Map();
|
|
814
835
|
/** TRAP bindings: declarations whose initializer provably throws before
|
|
815
836
|
* producing a value (its chain roots at an ambient-undefined name —
|
|
816
837
|
* ambientUndefVarRootOf). Module init unwinds at the declaration, so no
|
|
@@ -1090,7 +1111,7 @@ export class Lowerer {
|
|
|
1090
1111
|
// the initializer cannot fall back to a narrowing adapter.
|
|
1091
1112
|
if (ts.isIdentifier(node) && fallback?.kind === "func") {
|
|
1092
1113
|
const decl = this.checker.valueDeclarationOf(symbol);
|
|
1093
|
-
if (decl && ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
1114
|
+
if (decl && ts.isVariableDeclaration(decl) && !decl.type && !hasJsTypeAnnotation(decl) && decl.initializer) {
|
|
1094
1115
|
let init = decl.initializer;
|
|
1095
1116
|
while (ts.isParenthesizedExpression(init))
|
|
1096
1117
|
init = init.expression;
|
|
@@ -1124,14 +1145,14 @@ export class Lowerer {
|
|
|
1124
1145
|
}
|
|
1125
1146
|
/** Recover the original optional union when a checked single-arm helper
|
|
1126
1147
|
* was installed before a strict property consumer could name its member.
|
|
1127
|
-
* Recovery
|
|
1128
|
-
*
|
|
1148
|
+
* Recovery covers member reads and storage roots marked by the
|
|
1149
|
+
* optional-read analysis, so ordinary assertions keep their generic
|
|
1129
1150
|
* checked-narrow behavior. */
|
|
1130
1151
|
runtimeOptionalSourceValue(node, value) {
|
|
1131
1152
|
let origin = node;
|
|
1132
1153
|
while (ts.isParenthesizedExpression(origin))
|
|
1133
1154
|
origin = origin.expression;
|
|
1134
|
-
let optionalOrigin = ts.isElementAccessExpression(origin);
|
|
1155
|
+
let optionalOrigin = ts.isElementAccessExpression(origin) || ts.isPropertyAccessExpression(origin);
|
|
1135
1156
|
if (ts.isIdentifier(origin)) {
|
|
1136
1157
|
const local = this.resolveLocal(origin);
|
|
1137
1158
|
const root = local ? this.runtimeOptionalRootOf(local) : null;
|
|
@@ -1143,6 +1164,10 @@ export class Lowerer {
|
|
|
1143
1164
|
}
|
|
1144
1165
|
if (!optionalOrigin)
|
|
1145
1166
|
return null;
|
|
1167
|
+
// A checked JavaScript indexed read can already be boxed. The checker
|
|
1168
|
+
// calls the element present, but that inference is not a runtime guard.
|
|
1169
|
+
if (isJsSourceFile(node.getSourceFile()) && value.kind === "dynCheck" && value.value.type.kind === "dyn")
|
|
1170
|
+
return value.value;
|
|
1146
1171
|
let source = value;
|
|
1147
1172
|
if (value.kind === "call" &&
|
|
1148
1173
|
this.checkedNarrowHelpers.has(value.callee) &&
|
|
@@ -1348,10 +1373,12 @@ export class Lowerer {
|
|
|
1348
1373
|
copyRetagHelpers = new Map();
|
|
1349
1374
|
unionLiteralOwners = new Map();
|
|
1350
1375
|
strippedUndefinedArms = new Map();
|
|
1376
|
+
addedUndefinedArms = new Map();
|
|
1351
1377
|
stdlibSymbols = new Map();
|
|
1352
1378
|
/** Method adapter names are owned by class-method-values. Looking them
|
|
1353
1379
|
* up must not scan and retain every unrelated lifted function. */
|
|
1354
1380
|
classMethodValueHelpers = new Set();
|
|
1381
|
+
classMethodValueSelections = new Map();
|
|
1355
1382
|
/** Callee names of every interned coercion helper whose CALL mints a
|
|
1356
1383
|
* FRESH closure per evaluation (%fn.width.*, %fn.adapt.*,
|
|
1357
1384
|
* %fnval.spawnres.*). Registered at the mint site — NOT recovered by
|
|
@@ -1442,9 +1469,15 @@ export class Lowerer {
|
|
|
1442
1469
|
/** Inferred JS methods participating in an override chain keep a vtable
|
|
1443
1470
|
* ABI instead of call-site specialization. Filled before class collection. */
|
|
1444
1471
|
virtualJsMethods = new Set();
|
|
1472
|
+
/** Descendant writes must widen the original JS field before collecting
|
|
1473
|
+
* any class layout; base and derived instances share its storage ABI. */
|
|
1474
|
+
inheritedJsFieldWrites = new Map();
|
|
1445
1475
|
/** Largest fixed argument list below a JS method, discovered before any
|
|
1446
1476
|
* base vtable signature is collected. Unused checked slots carry undefined. */
|
|
1447
1477
|
virtualJsMethodArity = new Map();
|
|
1478
|
+
checkedVirtualJsMethods = new Set();
|
|
1479
|
+
checkedVirtualJsAccessors = new Set();
|
|
1480
|
+
checkedVirtualJsValueReturns = new Set();
|
|
1448
1481
|
/** The class whose members are lowering — `super` binds lexically to it
|
|
1449
1482
|
* (arrows inside methods lower within this window, so they see it too). */
|
|
1450
1483
|
currentClass = null;
|
|
@@ -1583,6 +1616,7 @@ export class Lowerer {
|
|
|
1583
1616
|
* a reference to a lowerable body reports its name here — recorded even
|
|
1584
1617
|
* when the enclosing statement later poisons. */
|
|
1585
1618
|
onEdge = null;
|
|
1619
|
+
deferredModuleInitializers = null;
|
|
1586
1620
|
// Stack of function contexts (bottom = the function being declared at
|
|
1587
1621
|
// top level, top = the innermost nested function currently lowering).
|
|
1588
1622
|
fnStack = [];
|
|
@@ -1621,6 +1655,15 @@ export class Lowerer {
|
|
|
1621
1655
|
* is assembled directly. The configured reachable set remains null so
|
|
1622
1656
|
* demand-driven instance lowering keeps its existing gates. */
|
|
1623
1657
|
reachableForArtifacts = null;
|
|
1658
|
+
/** Constructors retained by the active worklist. A boxed base receiver
|
|
1659
|
+
* can contain any retained descendant, but importing its declaration
|
|
1660
|
+
* alone does not make every descendant constructible. */
|
|
1661
|
+
constructedClasses = null;
|
|
1662
|
+
virtualEdges = new Map();
|
|
1663
|
+
classCanBeConstructed(info) {
|
|
1664
|
+
return this.constructedClasses === null || this.constructedClasses.has(info.def.name) ||
|
|
1665
|
+
info.genericInstance !== undefined || info.mixinInstance !== undefined;
|
|
1666
|
+
}
|
|
1624
1667
|
/** Coverage remainder mode: the reachability gate inverts (see wantBody)
|
|
1625
1668
|
* and no module is built. */
|
|
1626
1669
|
remainder;
|
|
@@ -2467,8 +2510,11 @@ export class Lowerer {
|
|
|
2467
2510
|
if (!symbol)
|
|
2468
2511
|
return null;
|
|
2469
2512
|
const g = this.globalsBySymbol.get(symbol);
|
|
2470
|
-
if (g)
|
|
2513
|
+
if (g) {
|
|
2514
|
+
if (g.type.kind === "func")
|
|
2515
|
+
g.type = this.runtimeOptionalBindingType(ident, g.type);
|
|
2471
2516
|
return g;
|
|
2517
|
+
}
|
|
2472
2518
|
for (const d of this.checker.declarationsOf(symbol)) {
|
|
2473
2519
|
const byDecl = this.globalsByDeclNode.get(d);
|
|
2474
2520
|
if (byDecl)
|
|
@@ -2713,6 +2759,14 @@ export class Lowerer {
|
|
|
2713
2759
|
return null;
|
|
2714
2760
|
return s.flags & ts.SymbolFlags.Alias ? this.checker.getAliasedSymbol(s) : s;
|
|
2715
2761
|
};
|
|
2762
|
+
const signatureOf = (node) => {
|
|
2763
|
+
const symbol = symbolOf(node);
|
|
2764
|
+
if (!symbol)
|
|
2765
|
+
return null;
|
|
2766
|
+
const projection = this.staticCallables.get(symbol);
|
|
2767
|
+
return this.fnSigsBySymbol.get(symbol) ??
|
|
2768
|
+
(projection?.kind === "declared-function" ? projection.signature : null);
|
|
2769
|
+
};
|
|
2716
2770
|
const functionDeclBySymbol = new Map();
|
|
2717
2771
|
const signatureBySymbol = new Map();
|
|
2718
2772
|
const methodFamilies = new Map();
|
|
@@ -2736,7 +2790,7 @@ export class Lowerer {
|
|
|
2736
2790
|
});
|
|
2737
2791
|
}
|
|
2738
2792
|
for (const info of this.classes.values()) {
|
|
2739
|
-
for (const { mName, member } of this.classMethodMembers(info)) {
|
|
2793
|
+
for (const { mName, member } of this.classMethodMembers(info, true)) {
|
|
2740
2794
|
if (!member.name || !(ts.isIdentifier(member.name) || ts.isStringLiteral(member.name)))
|
|
2741
2795
|
continue;
|
|
2742
2796
|
const symbol = symbolOf(member.name);
|
|
@@ -2866,9 +2920,11 @@ export class Lowerer {
|
|
|
2866
2920
|
}
|
|
2867
2921
|
if (ts.isBinaryExpression(e)) {
|
|
2868
2922
|
const op = e.operatorToken.kind;
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2923
|
+
// Nullish/falsy left values select the fallback, so only that
|
|
2924
|
+
// fallback can make the whole expression undefined.
|
|
2925
|
+
if (op === ts.SyntaxKind.BarBarToken || op === ts.SyntaxKind.QuestionQuestionToken)
|
|
2926
|
+
return mayBeOptional(e.right);
|
|
2927
|
+
if (op === ts.SyntaxKind.AmpersandAmpersandToken)
|
|
2872
2928
|
return mayBeOptional(e.left) || mayBeOptional(e.right);
|
|
2873
2929
|
}
|
|
2874
2930
|
if (ts.isPropertyAccessExpression(e) && ts.isIdentifier(e.expression)) {
|
|
@@ -2994,6 +3050,29 @@ export class Lowerer {
|
|
|
2994
3050
|
found = true;
|
|
2995
3051
|
return found;
|
|
2996
3052
|
};
|
|
3053
|
+
const jsLambdas = [];
|
|
3054
|
+
for (const sf of sourceFiles) {
|
|
3055
|
+
if (!isJsSourceFile(sf))
|
|
3056
|
+
continue;
|
|
3057
|
+
ts.walkPreorder(sf, (node) => {
|
|
3058
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node))
|
|
3059
|
+
jsLambdas.push(node);
|
|
3060
|
+
});
|
|
3061
|
+
}
|
|
3062
|
+
for (const [symbol, signature] of signatureBySymbol) {
|
|
3063
|
+
const declaration = functionDeclBySymbol.get(symbol);
|
|
3064
|
+
if (!declaration || !isJsSourceFile(declaration.getSourceFile()))
|
|
3065
|
+
continue;
|
|
3066
|
+
const checked = this.checker.getSignatureFromDeclaration(declaration);
|
|
3067
|
+
const checkedReturn = checked ? this.checker.getReturnTypeOfSignature(checked) : null;
|
|
3068
|
+
// Checker-known optional results already narrow at each use. Only
|
|
3069
|
+
// propagate undefined that JavaScript's runtime ABI adds beyond them.
|
|
3070
|
+
if (checkedReturn && ((checkedReturn.flags & ts.TypeFlags.Undefined) !== 0 ||
|
|
3071
|
+
checkedReturn.isUnionType() && ts.constituentTypes(checkedReturn).some((arm) => (arm.flags & ts.TypeFlags.Undefined) !== 0)))
|
|
3072
|
+
continue;
|
|
3073
|
+
if (signature.returnType.kind === "union" && this.armTag(signature.returnType.unionId, UNDEFINED_T) >= 0)
|
|
3074
|
+
optionalReturns.add(symbol);
|
|
3075
|
+
}
|
|
2997
3076
|
const promoteHofCallback = (callback, parameterIndices, seen = new Set()) => {
|
|
2998
3077
|
let changed = false;
|
|
2999
3078
|
const checkerTypeContainsTypeParameter = (type) => {
|
|
@@ -3381,21 +3460,32 @@ export class Lowerer {
|
|
|
3381
3460
|
}
|
|
3382
3461
|
return;
|
|
3383
3462
|
}
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
if (
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
const
|
|
3393
|
-
if (
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3463
|
+
// A virtual slot has one argument representation, even when
|
|
3464
|
+
// the unchecked read reaches only a base-typed call site.
|
|
3465
|
+
// Promote every implementation and its parameter bindings so
|
|
3466
|
+
// downstream calls and returns see the same optional value.
|
|
3467
|
+
const family = familyBySymbol.get(symbol);
|
|
3468
|
+
if (family)
|
|
3469
|
+
optionalMethodFamilies.add(family);
|
|
3470
|
+
for (const target of family ?? [symbol]) {
|
|
3471
|
+
const parameterShape = signatureBySymbol.get(target)?.params[i];
|
|
3472
|
+
if (!parameterShape)
|
|
3473
|
+
continue;
|
|
3474
|
+
parameterShape.type = addUndefined(parameterShape.type);
|
|
3475
|
+
const set = optionalParams.get(target) ?? new Set();
|
|
3476
|
+
const before = set.size;
|
|
3477
|
+
set.add(i);
|
|
3478
|
+
optionalParams.set(target, set);
|
|
3479
|
+
if (set.size !== before) {
|
|
3480
|
+
changed = true;
|
|
3481
|
+
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
3482
|
+
if (parameter) {
|
|
3483
|
+
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
3484
|
+
const boundSymbol = symbolOf(bound);
|
|
3485
|
+
if (boundSymbol && !optionalSymbols.has(boundSymbol)) {
|
|
3486
|
+
optionalSymbols.add(boundSymbol);
|
|
3487
|
+
changed = true;
|
|
3488
|
+
}
|
|
3399
3489
|
}
|
|
3400
3490
|
}
|
|
3401
3491
|
}
|
|
@@ -3431,6 +3521,23 @@ export class Lowerer {
|
|
|
3431
3521
|
for (const [symbol, decl] of functionDeclBySymbol)
|
|
3432
3522
|
if (scanReturns(symbol, decl))
|
|
3433
3523
|
changed = true;
|
|
3524
|
+
for (const fn of jsLambdas) {
|
|
3525
|
+
if (!bodyReturnsOptional(fn))
|
|
3526
|
+
continue;
|
|
3527
|
+
const mapped = this.mapTypeOf(this.typeOf(fn));
|
|
3528
|
+
if (mapped?.kind !== "func")
|
|
3529
|
+
continue;
|
|
3530
|
+
const previous = this.runtimeOptionalFunctionReturnType(fn, mapped.ret);
|
|
3531
|
+
if (previous.kind === "generator")
|
|
3532
|
+
continue;
|
|
3533
|
+
const next = previous.kind === "promise"
|
|
3534
|
+
? { ...previous, inner: this.runtimeOptionalType(previous.inner) }
|
|
3535
|
+
: this.runtimeOptionalType(previous);
|
|
3536
|
+
if (!typeEquals(previous, next)) {
|
|
3537
|
+
this.runtimeOptionalFunctionReturns.set(fn, next);
|
|
3538
|
+
changed = true;
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3434
3541
|
// Every implementation of a virtual slot must retain the same ABI,
|
|
3435
3542
|
// including when just one body forwards an omitted parameter.
|
|
3436
3543
|
for (const family of optionalMethodFamilies) {
|
|
@@ -3475,6 +3582,14 @@ export class Lowerer {
|
|
|
3475
3582
|
this.runtimeOptionalFunctionReturns.set(decl, arithmetic);
|
|
3476
3583
|
}
|
|
3477
3584
|
}
|
|
3585
|
+
for (const [declaration, global] of this.globalsByDeclNode) {
|
|
3586
|
+
if (global.type.kind !== "func" || !ts.isBinaryExpression(declaration) || !isJsSourceFile(declaration.getSourceFile()))
|
|
3587
|
+
continue;
|
|
3588
|
+
const value = peel(declaration.right);
|
|
3589
|
+
if (!ts.isFunctionExpression(value) && !ts.isArrowFunction(value))
|
|
3590
|
+
continue;
|
|
3591
|
+
global.type = { ...global.type, ret: this.runtimeOptionalFunctionReturnType(value, global.type.ret) };
|
|
3592
|
+
}
|
|
3478
3593
|
for (const sf of sourceFiles) {
|
|
3479
3594
|
ts.walkPreorder(sf, (node) => {
|
|
3480
3595
|
if (!ts.isVariableDeclaration(node) || !ts.isIdentifier(node.name))
|
|
@@ -3482,6 +3597,23 @@ export class Lowerer {
|
|
|
3482
3597
|
const symbol = symbolOf(node.name);
|
|
3483
3598
|
if (!symbol)
|
|
3484
3599
|
return;
|
|
3600
|
+
if (isJsSourceFile(sf) && !node.type && !hasJsTypeAnnotation(node) && node.initializer &&
|
|
3601
|
+
(ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer))) {
|
|
3602
|
+
const global = this.globalsBySymbol.get(symbol);
|
|
3603
|
+
if (global?.type.kind === "func")
|
|
3604
|
+
global.type = { ...global.type, ret: this.runtimeOptionalFunctionReturnType(node.initializer, global.type.ret) };
|
|
3605
|
+
}
|
|
3606
|
+
if (!node.type && !hasJsTypeAnnotation(node) && node.initializer && ts.isIdentifier(node.initializer)) {
|
|
3607
|
+
const global = this.globalsBySymbol.get(symbol);
|
|
3608
|
+
const current = global?.type ?? this.mapTypeOf(this.typeOf(node.name));
|
|
3609
|
+
const source = current?.kind === "func" ? signatureOf(node.initializer) : null;
|
|
3610
|
+
if (source && current?.kind === "func") {
|
|
3611
|
+
const promoted = { ...current, params: source.params.filter((param) => param.mode !== "dynRest" && param.mode !== "arguments").map((param) => param.type), ret: source.returnType };
|
|
3612
|
+
this.runtimeOptionalBindingTypes.set(symbol, promoted);
|
|
3613
|
+
if (global)
|
|
3614
|
+
global.type = promoted;
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3485
3617
|
const fields = optionalFields.get(symbol);
|
|
3486
3618
|
if (!dynamicObjectEntryRows.has(symbol) && !optionalSymbols.has(symbol) && !fields)
|
|
3487
3619
|
return;
|
|
@@ -3492,7 +3624,7 @@ export class Lowerer {
|
|
|
3492
3624
|
if (!dynamicObjectEntryRows.has(symbol) && optionalSymbols.has(symbol))
|
|
3493
3625
|
promoted = addUndefined(promoted);
|
|
3494
3626
|
if (promoted.kind === "func" && node.initializer && ts.isIdentifier(node.initializer)) {
|
|
3495
|
-
const sourceSig =
|
|
3627
|
+
const sourceSig = signatureOf(node.initializer);
|
|
3496
3628
|
if (sourceSig) {
|
|
3497
3629
|
promoted = {
|
|
3498
3630
|
...promoted,
|
|
@@ -3692,6 +3824,7 @@ export class Lowerer {
|
|
|
3692
3824
|
* and the retained reachability worklist. */
|
|
3693
3825
|
finishModule(functions) {
|
|
3694
3826
|
finalizeClassMethodValues(this, functions);
|
|
3827
|
+
trackClassFieldCreation(this, functions);
|
|
3695
3828
|
// Globals typed by a class that never REGISTERED (a JS class whose
|
|
3696
3829
|
// collection fenced — Symbol-keyed fields, an unsupported base): the
|
|
3697
3830
|
// declaration statement and every use compiled to runtime fences, but
|
|
@@ -3862,6 +3995,7 @@ export class Lowerer {
|
|
|
3862
3995
|
* body; both fire edges through the same hooks and are not units
|
|
3863
3996
|
* themselves. */
|
|
3864
3997
|
emitReachable(extraRoots) {
|
|
3998
|
+
this.deferredModuleInitializers = new DeferredModuleInitializers();
|
|
3865
3999
|
const parts = this.splitFiles();
|
|
3866
4000
|
// Direct lowering callers do not necessarily run program preflight.
|
|
3867
4001
|
// Establish the same managed header/top-level batch here before
|
|
@@ -4028,6 +4162,7 @@ export class Lowerer {
|
|
|
4028
4162
|
return owner;
|
|
4029
4163
|
};
|
|
4030
4164
|
const reachable = new Set();
|
|
4165
|
+
this.constructedClasses = new Set();
|
|
4031
4166
|
const queue = [];
|
|
4032
4167
|
const loweredUnits = new Map();
|
|
4033
4168
|
const initFunctions = [];
|
|
@@ -4038,6 +4173,12 @@ export class Lowerer {
|
|
|
4038
4173
|
reachable.add(name);
|
|
4039
4174
|
if (units.has(name))
|
|
4040
4175
|
queue.push(name);
|
|
4176
|
+
if (this.constructedClasses && name.endsWith(".constructor")) {
|
|
4177
|
+
this.constructedClasses.add(name.slice(1, -".constructor".length));
|
|
4178
|
+
for (const [owner, methods] of this.virtualEdges)
|
|
4179
|
+
for (const method of methods)
|
|
4180
|
+
this.noteVirtualEdge(owner, method);
|
|
4181
|
+
}
|
|
4041
4182
|
};
|
|
4042
4183
|
// Class EXPRESSIONS collect while init bodies lower (below): their
|
|
4043
4184
|
// member units register the moment collection finishes — before any
|
|
@@ -4188,10 +4329,13 @@ export class Lowerer {
|
|
|
4188
4329
|
const classDispatch = new ClassDynamicDispatch(extraRoots !== undefined);
|
|
4189
4330
|
for (;;) {
|
|
4190
4331
|
drainInstances();
|
|
4332
|
+
const initializerChanged = this.deferredModuleInitializers.process(this, [
|
|
4333
|
+
...loweredUnits.values(), ...initFunctions, ...instanceFunctions, ...this.liftedFns, ...this.implicitFns,
|
|
4334
|
+
]);
|
|
4191
4335
|
const dispatchChanged = classDispatch.process(this, [
|
|
4192
4336
|
...loweredUnits.values(), ...initFunctions, ...instanceFunctions, ...this.liftedFns, ...this.implicitFns,
|
|
4193
4337
|
]);
|
|
4194
|
-
if (queue.length === 0 && !dispatchChanged)
|
|
4338
|
+
if (queue.length === 0 && !dispatchChanged && !initializerChanged)
|
|
4195
4339
|
break;
|
|
4196
4340
|
drainUnits();
|
|
4197
4341
|
this.restoreGenericInstanceOrder(instLowered);
|
|
@@ -4214,6 +4358,20 @@ export class Lowerer {
|
|
|
4214
4358
|
...this.liftedFns,
|
|
4215
4359
|
...this.implicitFns,
|
|
4216
4360
|
];
|
|
4361
|
+
// The worklist can leave a virtual site with only its base method.
|
|
4362
|
+
// Devirtualize after construction/override reachability has settled.
|
|
4363
|
+
for (const fn of functions)
|
|
4364
|
+
fn.body = transformStmtList(fn.body, { stmt: (statement) => statement, expr: (expression) => {
|
|
4365
|
+
if (expression.kind !== "virtualCall")
|
|
4366
|
+
return expression;
|
|
4367
|
+
const info = this.classes.get(expression.className);
|
|
4368
|
+
const method = info && this.findMethodOn(info, expression.method);
|
|
4369
|
+
if (!method || method.sig.abstract || [...this.classes.values()].some((candidate) => this.isSubclassOf(candidate.def.name, expression.className) && candidate.def.name !== expression.className &&
|
|
4370
|
+
candidate.methods.has(expression.method) && reachable.has(`%${candidate.def.name}.${expression.method}`)))
|
|
4371
|
+
return expression;
|
|
4372
|
+
return { kind: "call", callee: `%${method.declarer.def.name}.${expression.method}`,
|
|
4373
|
+
args: [this.upcastTo(expression.args[0], method.declarer.def.name), ...expression.args.slice(1)], type: expression.type, loc: expression.loc };
|
|
4374
|
+
} });
|
|
4217
4375
|
this.reachableForArtifacts = reachable;
|
|
4218
4376
|
return { reachable, result: this.finishModule(functions) };
|
|
4219
4377
|
}
|
|
@@ -4231,12 +4389,17 @@ export class Lowerer {
|
|
|
4231
4389
|
noteVirtualEdge(info, method) {
|
|
4232
4390
|
if (!this.onEdge)
|
|
4233
4391
|
return;
|
|
4392
|
+
if (this.constructedClasses) {
|
|
4393
|
+
const methods = this.virtualEdges.get(info) ?? new Set();
|
|
4394
|
+
methods.add(method);
|
|
4395
|
+
this.virtualEdges.set(info, methods);
|
|
4396
|
+
}
|
|
4234
4397
|
const above = this.findMethodOn(info, method);
|
|
4235
4398
|
if (above)
|
|
4236
4399
|
this.noteEdge(`%${above.declarer.def.name}.${method}`);
|
|
4237
4400
|
const below = (c) => {
|
|
4238
4401
|
for (const s of c.subclasses) {
|
|
4239
|
-
if (s.methods.has(method))
|
|
4402
|
+
if (this.classCanBeConstructed(s) && s.methods.has(method))
|
|
4240
4403
|
this.noteEdge(`%${s.def.name}.${method}`);
|
|
4241
4404
|
below(s);
|
|
4242
4405
|
}
|
|
@@ -4587,6 +4750,16 @@ export class Lowerer {
|
|
|
4587
4750
|
return fenceStaticReadableStreamMember(this, access, use);
|
|
4588
4751
|
}
|
|
4589
4752
|
typeOf(node) {
|
|
4753
|
+
if (ts.isPropertyAccessExpression(node) && isJsSourceFile(node.getSourceFile())) {
|
|
4754
|
+
const receiver = node.expression.kind === ts.SyntaxKind.ThisKeyword && this.fnStack.length > 0
|
|
4755
|
+
? this.resolveThis()?.type : this.mapTypeOf(this.checker.getTypeAtLocation(node.expression));
|
|
4756
|
+
const checkedThis = node.expression.kind === ts.SyntaxKind.ThisKeyword && this.fnStack.length > 0 && receiver?.kind === "dyn"
|
|
4757
|
+
? this.currentClass : null;
|
|
4758
|
+
if (receiver?.kind === "object" && this.classes.get(receiver.className)?.fields.get(node.name.text)?.kind === "dyn" ||
|
|
4759
|
+
checkedThis?.fields.get(node.name.text)?.kind === "dyn") {
|
|
4760
|
+
return this.checker.getUnknownType();
|
|
4761
|
+
}
|
|
4762
|
+
}
|
|
4590
4763
|
// A checked JS method receives its actual call-site receiver. Its
|
|
4591
4764
|
// declaration's inferred class type must not turn property reads back
|
|
4592
4765
|
// into native field loads when the method is borrowed by another object.
|
|
@@ -4637,8 +4810,15 @@ export class Lowerer {
|
|
|
4637
4810
|
// A checked value can contain any runtime kind. A checker-proven
|
|
4638
4811
|
// branch narrow therefore cannot contradict this specialization;
|
|
4639
4812
|
// reads still validate the payload through maybeNarrow.
|
|
4640
|
-
if (boundIr.kind === "dyn")
|
|
4641
|
-
|
|
4813
|
+
if (boundIr.kind === "dyn") {
|
|
4814
|
+
// JSDoc and initializer inference are declaration types, not flow
|
|
4815
|
+
// proofs. A checked specialization must not reinstate those
|
|
4816
|
+
// stale layouts (mutable/null slots and heterogeneous JS arrays).
|
|
4817
|
+
const declaration = sym && this.checker.valueDeclarationOf(sym);
|
|
4818
|
+
const declared = declaration && ts.isParameter(declaration)
|
|
4819
|
+
? this.mapTypeOf(this.checker.getTypeAtLocation(declaration.name)) : null;
|
|
4820
|
+
return declared && typeEquals(declared, narrowedIr) ? bound : t;
|
|
4821
|
+
}
|
|
4642
4822
|
// A union binding narrowed to one of its arms (typeof/equality
|
|
4643
4823
|
// guards over string|number bindings) — the narrow is truth.
|
|
4644
4824
|
if (boundIr.kind === "union") {
|
|
@@ -5063,7 +5243,14 @@ export class Lowerer {
|
|
|
5063
5243
|
// undefined/null literals store the dyn unit values. Types outside the
|
|
5064
5244
|
// dyn's domain (bytes, classes, Maps, ...) fall through to
|
|
5065
5245
|
// requireExactShape's SC1101 fence.
|
|
5066
|
-
//
|
|
5246
|
+
// Promise payloads may widen at a checked return boundary, including
|
|
5247
|
+
// arrays inferred as tuple results by Promise.all. Keep both payload
|
|
5248
|
+
// ABIs explicit: box settlement, then validate the destination payload.
|
|
5249
|
+
if (expected.kind === "promise" && expected.inner.kind !== "void" && expr.type.kind === "promise" &&
|
|
5250
|
+
!typeEquals(expected, expr.type) && this.dynConvertible(expr.type) &&
|
|
5251
|
+
canDynCheckTo(expected, (id) => this.shapes.get(id), (id) => this.unions.get(id))) {
|
|
5252
|
+
return { kind: "dynCheck", value: this.coerceToExpected(expr, DYN), type: expected, loc: expr.loc };
|
|
5253
|
+
}
|
|
5067
5254
|
// Promise<never> return holding a `return Promise.reject(value)` the
|
|
5068
5255
|
// dyn arm typed promise<dyn>): awaiting through the slot ignores the
|
|
5069
5256
|
// fulfillment payload (scr_await_void) and rejections flow untyped,
|
|
@@ -7749,7 +7936,7 @@ export class Lowerer {
|
|
|
7749
7936
|
// NamedEvaluation through a variable initializer) — inspect prints
|
|
7750
7937
|
// [Function: name] and call errors spell it, like Node.
|
|
7751
7938
|
if (e.kind === "dynFrom" && e.value.type.kind === "func" && e.fnName === undefined) {
|
|
7752
|
-
const name = jsFuncNameOf(node);
|
|
7939
|
+
const name = jsFuncNameOf(node, this);
|
|
7753
7940
|
if (name !== null)
|
|
7754
7941
|
e = { ...e, fnName: name };
|
|
7755
7942
|
}
|
|
@@ -8039,7 +8226,7 @@ export class Lowerer {
|
|
|
8039
8226
|
}
|
|
8040
8227
|
}
|
|
8041
8228
|
let e = this.lowerExpr(node);
|
|
8042
|
-
if (expected?.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0) {
|
|
8229
|
+
if (expected?.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0 || expected?.kind === "dyn" && isJsSourceFile(node.getSourceFile())) {
|
|
8043
8230
|
// A destination that accepts undefined must retain an unchecked
|
|
8044
8231
|
// read's storage value even when the checker still calls it present.
|
|
8045
8232
|
e = this.runtimeOptionalSourceValue(node, e) ?? e;
|
|
@@ -8100,7 +8287,19 @@ export class Lowerer {
|
|
|
8100
8287
|
* declared result type of an index-signature read under
|
|
8101
8288
|
* noUncheckedIndexedAccess. Null when the type cannot take the arm. */
|
|
8102
8289
|
withUndefinedArmOf(t) {
|
|
8103
|
-
|
|
8290
|
+
if (t.kind !== "union")
|
|
8291
|
+
return withUndefinedArmCanonical(t, this.unions);
|
|
8292
|
+
const cached = this.addedUndefinedArms.get(t.unionId);
|
|
8293
|
+
if (cached && cached.unions === this.unions.revision)
|
|
8294
|
+
return cached.type;
|
|
8295
|
+
// As with removing undefined, repeated optional-read propagation can
|
|
8296
|
+
// reuse the exact union transformation until a recursive contract closes.
|
|
8297
|
+
// An unknown id is not cached: a later interning can create it.
|
|
8298
|
+
if (!this.unions.get(t.unionId))
|
|
8299
|
+
return null;
|
|
8300
|
+
const type = withUndefinedArmCanonical(t, this.unions);
|
|
8301
|
+
this.addedUndefinedArms.set(t.unionId, { type, unions: this.unions.revision });
|
|
8302
|
+
return type;
|
|
8104
8303
|
}
|
|
8105
8304
|
/** True when a static type converts to a dyn value (the dynFrom
|
|
8106
8305
|
* walker's domain): JSON-safe, bytes<u8> (Uint8Array/Buffer — the checked-dynamic tree's
|
|
@@ -8562,9 +8761,10 @@ export class Lowerer {
|
|
|
8562
8761
|
lowerStaticFieldInits(info) {
|
|
8563
8762
|
return lowerStaticFieldInits(this, info);
|
|
8564
8763
|
}
|
|
8565
|
-
/**
|
|
8566
|
-
*
|
|
8567
|
-
|
|
8764
|
+
/** Method-like members with their collected method-map names. Body
|
|
8765
|
+
* lowering omits abstract declarations; ABI analysis must include them
|
|
8766
|
+
* because an abstract-typed call selects the same virtual slot. */
|
|
8767
|
+
*classMethodMembers(info, includeAbstract = false) {
|
|
8568
8768
|
if (!info.decl)
|
|
8569
8769
|
return; // builtin error classes: runtime-provided bodies
|
|
8570
8770
|
for (const member of info.decl.members) {
|
|
@@ -8588,7 +8788,8 @@ export class Lowerer {
|
|
|
8588
8788
|
if (baseName === null)
|
|
8589
8789
|
continue;
|
|
8590
8790
|
const mName = ts.isMethodDeclaration(fnLike) ? baseName : `${ts.isGetAccessor(fnLike) ? "get" : "set"}:${baseName}`;
|
|
8591
|
-
|
|
8791
|
+
const signature = info.methods.get(mName);
|
|
8792
|
+
if (!signature || (!fnLike.body && !(includeAbstract && signature.abstract)))
|
|
8592
8793
|
continue;
|
|
8593
8794
|
yield { mName, member: fnLike };
|
|
8594
8795
|
}
|
|
@@ -9755,6 +9956,13 @@ export class Lowerer {
|
|
|
9755
9956
|
* member access that IS a module in its own right (`fs.promises` — the
|
|
9756
9957
|
* same object as node:fs/promises, Node's rule). Null otherwise. */
|
|
9757
9958
|
builtinNamespaceModuleOf(expr) {
|
|
9959
|
+
// Default and CommonJS process bindings alias the global object, whose
|
|
9960
|
+
// methods and properties keep their existing process lowerings.
|
|
9961
|
+
if (stdlibGlobalNameOf(this, expr) === "process")
|
|
9962
|
+
return null;
|
|
9963
|
+
const imported = ts.isIdentifier(expr) ? this.builtinImportOf(expr) : null;
|
|
9964
|
+
if (imported?.module === "util" && imported.member === "types")
|
|
9965
|
+
return "util/types";
|
|
9758
9966
|
const stored = ts.isIdentifier(expr)
|
|
9759
9967
|
? (this.peekLocal(expr)?.type ?? this.globalOf(expr)?.type)
|
|
9760
9968
|
: undefined;
|
|
@@ -10040,6 +10248,12 @@ export class Lowerer {
|
|
|
10040
10248
|
* deliberately narrower than table membership because many table rows
|
|
10041
10249
|
* are only dispatch sentinels for call-site-specific lowering. */
|
|
10042
10250
|
lowerBuiltinCallableValue(bi, loc) {
|
|
10251
|
+
if (bi.module === "util" && bi.member === "types")
|
|
10252
|
+
return utilTypesModuleValue(this, loc);
|
|
10253
|
+
if (bi.module === "util/types" && builtinModuleFnOf(this, bi.module, bi.member))
|
|
10254
|
+
return lowerUtilTypeValue(this, bi.member, loc);
|
|
10255
|
+
if (bi.module === "util" && bi.member === "getSystemErrorMap")
|
|
10256
|
+
return lowerSystemErrorMapValue(this, loc);
|
|
10043
10257
|
if (bi.module === "fs" && builtinModuleFnOf(this, bi.module, bi.member)?.fn === "fs.callbackCall") {
|
|
10044
10258
|
return { kind: "libCall", fn: "fs.callbackValue", args: [{ kind: "strLit", value: bi.member, type: STRING, loc }], type: DYN, loc };
|
|
10045
10259
|
}
|
|
@@ -10054,6 +10268,8 @@ export class Lowerer {
|
|
|
10054
10268
|
if (param.mode === "rest")
|
|
10055
10269
|
return { mode: "rest", type: arrayOf(param.type) };
|
|
10056
10270
|
if (param.mode === "optional") {
|
|
10271
|
+
if (param.type.kind === "dyn" && param.defaultValue === undefined)
|
|
10272
|
+
return { mode: "omittable", type: DYN };
|
|
10057
10273
|
return { mode: "omittable", type: this.withUndefinedArm(param.type), bodyType: param.type };
|
|
10058
10274
|
}
|
|
10059
10275
|
return { mode: "required", type: param.type };
|
|
@@ -10085,7 +10301,10 @@ export class Lowerer {
|
|
|
10085
10301
|
};
|
|
10086
10302
|
if (valueParam.mode !== "optional")
|
|
10087
10303
|
return ref;
|
|
10088
|
-
|
|
10304
|
+
// Checked runtime APIs consume undefined directly for omitted options.
|
|
10305
|
+
if (valueParam.type.kind === "dyn" && valueParam.defaultValue === undefined)
|
|
10306
|
+
return ref;
|
|
10307
|
+
if (valueParam.defaultValue === undefined || (valueParam.type.kind !== "string" && valueParam.type.kind !== "f64") || param.type.kind !== "union") {
|
|
10089
10308
|
throw new InternalCompilerError(`builtin callable value '${display}' has an unsupported optional default`);
|
|
10090
10309
|
}
|
|
10091
10310
|
const undefTag = this.armTag(param.type.unionId, UNDEFINED_T);
|