@scriptc/compiler 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +59 -4
- package/dist/backend/llvm/dyn.d.ts +3 -0
- package/dist/backend/llvm/dyn.js +84 -12
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +4 -1
- package/dist/backend/llvm/emitter.js +20 -5
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +9 -1
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +5 -0
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +30 -5
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +70 -9
- 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 +35 -1
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/may-throw.js +4 -0
- package/dist/backend/may-throw.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/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/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/containers/bytes.js +17 -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/lower-builtins.d.ts +4 -9
- package/dist/frontend/lowering/lower-builtins.js +291 -51
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +283 -73
- 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 +439 -25
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +1 -1
- package/dist/frontend/lowering/lower-containers.js +39 -17
- 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 +294 -129
- 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 +15 -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 +100 -35
- 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-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 +26 -9
- package/dist/frontend/lowering/lowerer.js +218 -27
- 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 +1 -0
- package/dist/frontend/lowering/surfaces.js +24 -12
- 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/program.js +4 -2
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/type-mapper.js +83 -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 +16 -10
- package/dist/index.js.map +1 -1
- package/dist/ir/ir.d.ts +27 -13
- package/dist/ir/ir.js +26 -2
- package/dist/ir/ir.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 +56 -5
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +17 -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/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/package.json +20 -20
- package/surface-manifest.json +115 -13
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { everyStmtList, everyTypeChild } from "../../ir/traverse.js";
|
|
1
2
|
import { InternalCompilerError } from "../../errors.js";
|
|
2
3
|
/* Module-graph lowering: splitting each source file into its parts, the
|
|
3
4
|
* program-collection pass (signatures, classes, globals — reachability
|
|
@@ -17,7 +18,7 @@ import { ENTRY_NAME, PoisonError, boundIdentifiersOf, dynFallbackType, dynUndefi
|
|
|
17
18
|
import { isNativeFfiRequire, builtinMemberRequireDecl, builtinNamespaceDestructureModuleOf, createRequireBindingDecl, createRequireNamespaceDecl, createRequireProgramModuleDecl, createRequireSpecOf, isPromisifyCall, registerBuiltinCallableAlias, stripTypeCasts } from "./lower-builtins.js";
|
|
18
19
|
import { bindingContextualGenericFnNodeOf, bindingGenericFnAliasInfoOf, bindingGenericFnInfoOf, bindingGenericFnNodeOf, bindingNeverReassigned, deadUnmappableBinding, funcTypeFromParamShapes, implicitLocalFnInfoOf, implicitLocalFnNodeOf, nullishGenericBindingUnitOf, registerOverloadedCallableAlias } from "./lower-calls.js";
|
|
19
20
|
import { jsBindingHasOpenWrites, hasJsTypeAnnotation, isVarDeclared, numericIteratorSourceOf, provenanceElidedConstDecl } from "./lower-stmts.js";
|
|
20
|
-
import {
|
|
21
|
+
import { objectFactoryGlobalType } from "./object-factory-new.js";
|
|
21
22
|
import { streamClassAliasDecl } from "./lower-stream.js";
|
|
22
23
|
import { stdlibGlobalAliasDecl, stdlibGlobalAliasNameOf, stdlibGlobalNameOf } from "./surfaces.js";
|
|
23
24
|
import { isNativeBuiltinValueInitializer } from "./lower-builtin-values.js";
|
|
@@ -25,7 +26,7 @@ import { collectNamespaceStmt, nsMemberIdentOf, nsPathPrefix, trapDeclRootOf } f
|
|
|
25
26
|
import { collectExpandoMembers } from "./lower-expando.js";
|
|
26
27
|
import { recordTextCodecClass } from "../../ir/ir.js";
|
|
27
28
|
import { isUnitOnlyTsType, unitOnlyUnion } from "../type-mapper.js";
|
|
28
|
-
import { collectVirtualJsMethods, decoratorNodesOf, genericIfaceBindingKeepsClass, guaranteedDecorationThrow, storedClassValueType } from "./lower-classes.js";
|
|
29
|
+
import { collectInheritedJsFieldWrites, collectVirtualJsMethods, decoratorNodesOf, genericIfaceBindingKeepsClass, guaranteedDecorationThrow, storedClassValueType } from "./lower-classes.js";
|
|
29
30
|
import { isMixinFnBinding, mixinResultBindingClassOf } from "./lower-mixins.js";
|
|
30
31
|
import { cjsModuleRef, cjsModuleRegistryPrelude } from "./lower-node-module.js";
|
|
31
32
|
import { forkTargetPaths } from "../fork-target.js";
|
|
@@ -259,6 +260,7 @@ export function collectProgram(lowerer, parts) {
|
|
|
259
260
|
lowerer.collecting = true;
|
|
260
261
|
try {
|
|
261
262
|
collectVirtualJsMethods(lowerer, parts.map((part) => part.sf));
|
|
263
|
+
collectInheritedJsFieldWrites(lowerer, parts.map((part) => part.sf));
|
|
262
264
|
for (const fp of parts)
|
|
263
265
|
for (const decl of fp.classDecls)
|
|
264
266
|
if (!computed.has(decl))
|
|
@@ -723,15 +725,14 @@ export function collectJsonImports(lowerer, parts) {
|
|
|
723
725
|
/** The classes, records, and unions the emitted module carries: exactly
|
|
724
726
|
* what the lowered functions and globals reference, closed transitively
|
|
725
727
|
* over record fields, union arms, class field types, base chains, and
|
|
726
|
-
*
|
|
727
|
-
* dropping an unused subclass must not turn its base into a standalone
|
|
728
|
-
* class at emit time). Registry entries interned while collecting
|
|
728
|
+
* constructible descendants and their base chains. Registry entries interned while collecting
|
|
729
729
|
* signatures nothing reaches stay out — an unreached type leaves no
|
|
730
730
|
* trace. A referenced class with no registration had its collection
|
|
731
731
|
* deferred: the reference flushes those diagnostics. Methods whose
|
|
732
732
|
* bodies were not lowered leave the def's method list, so vtable slots
|
|
733
733
|
* exist exactly for emitted overrides. */
|
|
734
734
|
export function moduleArtifacts(lowerer, functions) {
|
|
735
|
+
const valueInstanceOfRoots = new Set();
|
|
735
736
|
const classNames = new Set();
|
|
736
737
|
const shapeIds = new Set();
|
|
737
738
|
const unionIds = new Set();
|
|
@@ -759,56 +760,137 @@ export function moduleArtifacts(lowerer, functions) {
|
|
|
759
760
|
default: return false;
|
|
760
761
|
}
|
|
761
762
|
};
|
|
762
|
-
const
|
|
763
|
-
if (
|
|
764
|
-
// This walk only reads compiler-owned arrays. A callback traversal
|
|
765
|
-
// reuses one checked view instead of refreshing it at each step.
|
|
766
|
-
node.forEach(visit);
|
|
763
|
+
const visitClass = (name) => {
|
|
764
|
+
if (classNames.has(name))
|
|
767
765
|
return;
|
|
768
|
-
|
|
769
|
-
|
|
766
|
+
classNames.add(name);
|
|
767
|
+
pendingClasses.push(name);
|
|
768
|
+
};
|
|
769
|
+
const visitShape = (id) => {
|
|
770
|
+
if (shapeIds.has(id))
|
|
770
771
|
return;
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
772
|
+
shapeIds.add(id);
|
|
773
|
+
pendingShapes.push(id);
|
|
774
|
+
};
|
|
775
|
+
const visitUnion = (id) => {
|
|
776
|
+
if (unionIds.has(id))
|
|
777
|
+
return;
|
|
778
|
+
unionIds.add(id);
|
|
779
|
+
pendingUnions.push(id);
|
|
780
|
+
};
|
|
781
|
+
const visitType = (type) => {
|
|
782
|
+
switch (type.kind) {
|
|
783
|
+
case "object":
|
|
784
|
+
case "classval":
|
|
785
|
+
visitClass(type.className);
|
|
786
|
+
break;
|
|
787
|
+
case "record":
|
|
788
|
+
visitShape(type.shapeId);
|
|
789
|
+
break;
|
|
790
|
+
case "union":
|
|
791
|
+
visitUnion(type.unionId);
|
|
792
|
+
break;
|
|
791
793
|
}
|
|
794
|
+
return everyTypeChild(type, visitType);
|
|
795
|
+
};
|
|
796
|
+
const visitor = {
|
|
797
|
+
expr: (node) => {
|
|
798
|
+
visitType(node.type);
|
|
799
|
+
switch (node.kind) {
|
|
800
|
+
case "fieldIncDec":
|
|
801
|
+
case "new":
|
|
802
|
+
case "classRef":
|
|
803
|
+
case "instanceOf":
|
|
804
|
+
case "virtualCall":
|
|
805
|
+
case "fieldGet":
|
|
806
|
+
case "caughtCheck":
|
|
807
|
+
visitClass(node.className);
|
|
808
|
+
break;
|
|
809
|
+
case "caughtTest":
|
|
810
|
+
if (node.className !== undefined)
|
|
811
|
+
visitClass(node.className);
|
|
812
|
+
break;
|
|
813
|
+
case "recordGet":
|
|
814
|
+
case "recordKeyGet":
|
|
815
|
+
case "recordOvfKeys":
|
|
816
|
+
case "recordOvfHas":
|
|
817
|
+
visitShape(node.shapeId);
|
|
818
|
+
break;
|
|
819
|
+
case "unionWrap":
|
|
820
|
+
case "unionFuncEq":
|
|
821
|
+
case "unionNarrow":
|
|
822
|
+
case "unionDisc":
|
|
823
|
+
case "unionKeyGet":
|
|
824
|
+
case "unionIsTag":
|
|
825
|
+
case "unionEq":
|
|
826
|
+
visitUnion(node.unionId);
|
|
827
|
+
break;
|
|
828
|
+
case "yieldExpr":
|
|
829
|
+
if (node.captureCompletion !== undefined)
|
|
830
|
+
visitType(node.captureCompletion.returnType);
|
|
831
|
+
break;
|
|
832
|
+
case "instanceOfValue":
|
|
833
|
+
for (const type of [node.value.type, node.classValue.type]) {
|
|
834
|
+
if (type.kind !== "object" && type.kind !== "classval")
|
|
835
|
+
continue;
|
|
836
|
+
let root = lowerer.classes.get(type.className);
|
|
837
|
+
if (!root)
|
|
838
|
+
continue;
|
|
839
|
+
while (root.base)
|
|
840
|
+
root = root.base;
|
|
841
|
+
valueInstanceOfRoots.add(root.def.name);
|
|
842
|
+
}
|
|
843
|
+
break;
|
|
844
|
+
case "dynFrom":
|
|
845
|
+
if (boxedChild(node.value.type)) {
|
|
846
|
+
// A generic child can expose native stdio without importing stream.
|
|
847
|
+
visitClass("%Readable");
|
|
848
|
+
visitClass("%Writable");
|
|
849
|
+
}
|
|
850
|
+
break;
|
|
851
|
+
default:
|
|
852
|
+
// A new node with a named artifact reference must join this switch.
|
|
853
|
+
node;
|
|
854
|
+
}
|
|
855
|
+
return true;
|
|
856
|
+
},
|
|
857
|
+
stmt: (node) => {
|
|
858
|
+
switch (node.kind) {
|
|
859
|
+
case "fieldSet":
|
|
860
|
+
visitClass(node.className);
|
|
861
|
+
break;
|
|
862
|
+
case "recordSet":
|
|
863
|
+
case "recordKeySet":
|
|
864
|
+
case "recordKeyDelete":
|
|
865
|
+
visitShape(node.shapeId);
|
|
866
|
+
break;
|
|
867
|
+
default:
|
|
868
|
+
node;
|
|
869
|
+
}
|
|
870
|
+
return true;
|
|
871
|
+
},
|
|
792
872
|
};
|
|
793
|
-
//
|
|
794
|
-
//
|
|
795
|
-
// nodes and individual types need the general dependency walk.
|
|
873
|
+
// Visit compiler-owned typed storage and executable trees directly, without
|
|
874
|
+
// creating dynamic snapshots of every node's properties and metadata.
|
|
796
875
|
for (const fn of functions) {
|
|
797
876
|
for (const param of fn.params)
|
|
798
|
-
|
|
799
|
-
|
|
877
|
+
visitType(param.type);
|
|
878
|
+
visitType(fn.returnType);
|
|
800
879
|
for (const local of fn.locals)
|
|
801
|
-
|
|
880
|
+
visitType(local.type);
|
|
802
881
|
for (const capture of fn.captures ?? [])
|
|
803
|
-
|
|
882
|
+
visitType(capture.type);
|
|
804
883
|
for (const capture of fn.classCaptures ?? [])
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
884
|
+
visitType(capture.type);
|
|
885
|
+
if (fn.generator !== undefined) {
|
|
886
|
+
visitType(fn.generator.yieldT);
|
|
887
|
+
visitType(fn.generator.nextT);
|
|
888
|
+
visitType(fn.generator.resultType);
|
|
889
|
+
}
|
|
890
|
+
everyStmtList(fn.body, visitor);
|
|
809
891
|
}
|
|
810
892
|
for (const global of lowerer.globalsList)
|
|
811
|
-
|
|
893
|
+
visitType(global.type);
|
|
812
894
|
// The builtin error classes ride EVERY module: the runtime's own throws
|
|
813
895
|
// (JSON/dynCheck/regex failures) mint instances of them whether or not
|
|
814
896
|
// user code mentions Error, and the uncaught printer tells Error
|
|
@@ -829,12 +911,19 @@ export function moduleArtifacts(lowerer, functions) {
|
|
|
829
911
|
// overflow-valued shape (`{ [key: string]: {script?: string} }`)
|
|
830
912
|
// references its value shape through indexValue alone.
|
|
831
913
|
const shape = lowerer.shapes.get(pendingShapes.pop());
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
914
|
+
if (shape !== undefined) {
|
|
915
|
+
for (const field of shape.fields)
|
|
916
|
+
visitType(field.type);
|
|
917
|
+
if (shape.indexValue !== undefined)
|
|
918
|
+
visitType(shape.indexValue);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
while (pendingUnions.length > 0) {
|
|
922
|
+
const union = lowerer.unions.get(pendingUnions.pop());
|
|
923
|
+
if (union !== undefined)
|
|
924
|
+
for (const arm of union.arms)
|
|
925
|
+
visitType(arm);
|
|
835
926
|
}
|
|
836
|
-
while (pendingUnions.length > 0)
|
|
837
|
-
visit(lowerer.unions.get(pendingUnions.pop())?.arms);
|
|
838
927
|
while (pendingClasses.length > 0) {
|
|
839
928
|
const name = pendingClasses.pop();
|
|
840
929
|
const info = lowerer.classes.get(name);
|
|
@@ -844,15 +933,17 @@ export function moduleArtifacts(lowerer, functions) {
|
|
|
844
933
|
lowerer.flushDeferredClass(name);
|
|
845
934
|
continue;
|
|
846
935
|
}
|
|
847
|
-
|
|
936
|
+
for (const field of info.def.fields)
|
|
937
|
+
visitType(field.type);
|
|
848
938
|
if (info.base)
|
|
849
|
-
|
|
939
|
+
visitClass(info.base.def.name);
|
|
850
940
|
if (lowerer.inHierarchy(info)) {
|
|
851
941
|
let root = info;
|
|
852
942
|
while (root.base)
|
|
853
943
|
root = root.base;
|
|
854
944
|
const wholeTree = (c) => {
|
|
855
|
-
|
|
945
|
+
if (valueInstanceOfRoots.has(root.def.name) || lowerer.classCanBeConstructed(c))
|
|
946
|
+
visitClass(c.def.name);
|
|
856
947
|
for (const s of c.subclasses)
|
|
857
948
|
wholeTree(s);
|
|
858
949
|
};
|
|
@@ -1121,6 +1212,10 @@ export function collectGlobals(lowerer, sf, topStmts) {
|
|
|
1121
1212
|
let type = lowerer.mapTypeOf(tsType) ?? dynFallbackType(lowerer, stmt.expression, tsType);
|
|
1122
1213
|
if (type === null)
|
|
1123
1214
|
lowerer.badType(stmt.expression, tsType);
|
|
1215
|
+
// Inferred JavaScript factory exports keep their original value,
|
|
1216
|
+
// including callable objects decorated with Object.assign.
|
|
1217
|
+
if (isJsSourceFile(sf) && ts.isCallExpression(stmt.expression) && type.kind === "record" && lowerer.dynConvertible(type))
|
|
1218
|
+
type = DYN;
|
|
1124
1219
|
// `export default undefined` — the unit-only union, like any
|
|
1125
1220
|
// unit-only binding (`export default null` maps via mapType).
|
|
1126
1221
|
if (type.kind === "void" && isUnitOnlyTsType(tsType)) {
|
|
@@ -1169,16 +1264,9 @@ export function collectGlobals(lowerer, sf, topStmts) {
|
|
|
1169
1264
|
const t = lowerer.mapTypeOf(strict) ?? dynFallbackType(lowerer, nameNode, strict);
|
|
1170
1265
|
if (!t || t.kind === "void")
|
|
1171
1266
|
lowerer.badType(typeNode, strict);
|
|
1172
|
-
//
|
|
1173
|
-
//
|
|
1174
|
-
//
|
|
1175
|
-
// owner, identity by construction (a record-typed second slot
|
|
1176
|
-
// would either copy or mismatch the dyn value — that mismatch
|
|
1177
|
-
// was an ICE; a second same-named global double-released at
|
|
1178
|
-
// teardown). The statement's assign degenerates to a harmless
|
|
1179
|
-
// self-assign. Mutable (`let`) sources keep the registration
|
|
1180
|
-
// below: Node copies the VALUE at this statement, and separate
|
|
1181
|
-
// storage is exactly that copy.
|
|
1267
|
+
// An immutable export source shares its live storage and native
|
|
1268
|
+
// callable ABI. Mutable sources need a separate snapshot slot:
|
|
1269
|
+
// later writes to the binding do not change the exported value.
|
|
1182
1270
|
{
|
|
1183
1271
|
let rhs = typeNode;
|
|
1184
1272
|
while (ts.isParenthesizedExpression(rhs))
|
|
@@ -1186,19 +1274,14 @@ export function collectGlobals(lowerer, sf, topStmts) {
|
|
|
1186
1274
|
if (ts.isIdentifier(rhs)) {
|
|
1187
1275
|
const vSym = lowerer.checker.getSymbolAtLocation(rhs);
|
|
1188
1276
|
const vG = vSym && lowerer.globalsBySymbol.get(vSym);
|
|
1189
|
-
if (vG
|
|
1277
|
+
if (vG) {
|
|
1190
1278
|
if (!vG.mutable) {
|
|
1191
1279
|
lowerer.globalsBySymbol.set(symbol, vG);
|
|
1192
1280
|
for (const d of lowerer.checker.declarationsOf(symbol))
|
|
1193
1281
|
lowerer.globalsByDeclNode.set(d, vG);
|
|
1194
1282
|
return;
|
|
1195
1283
|
}
|
|
1196
|
-
|
|
1197
|
-
// Node's copy-of-the-reference at this statement (later
|
|
1198
|
-
// reassignments of the let stay invisible through the
|
|
1199
|
-
// export). The id must not collide with the let's own
|
|
1200
|
-
// `%g.<tag><name>` global.
|
|
1201
|
-
const g = { id: `%g.${tag}%export.${name}`, name, type: DYN, mutable: false };
|
|
1284
|
+
const g = { id: `%g.${tag}%export.${name}`, name, type: vG.type, mutable: false };
|
|
1202
1285
|
lowerer.globalsBySymbol.set(symbol, g);
|
|
1203
1286
|
for (const d of lowerer.checker.declarationsOf(symbol))
|
|
1204
1287
|
lowerer.globalsByDeclNode.set(d, g);
|
|
@@ -1207,7 +1290,7 @@ export function collectGlobals(lowerer, sf, topStmts) {
|
|
|
1207
1290
|
}
|
|
1208
1291
|
}
|
|
1209
1292
|
}
|
|
1210
|
-
const g = { id: `%g.${tag}
|
|
1293
|
+
const g = { id: `%g.${tag}%export.${name}`, name, type: t, mutable: false };
|
|
1211
1294
|
lowerer.globalsBySymbol.set(symbol, g);
|
|
1212
1295
|
// Importer aliases resolve to a DISTINCT late-bound symbol with
|
|
1213
1296
|
// the same declaration — key the node too (globalOf's fallback).
|
|
@@ -1849,9 +1932,7 @@ export function collectGlobals(lowerer, sf, topStmts) {
|
|
|
1849
1932
|
// their own per-site runtime fences.
|
|
1850
1933
|
const factoryType = !isLet && isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) &&
|
|
1851
1934
|
ts.isIdentifier(decl.name) && nameNode === decl.name && decl.initializer && ts.isNewExpression(decl.initializer)
|
|
1852
|
-
?
|
|
1853
|
-
if (!factoryType && isJsSourceFile(sf) && !lowerer.mapTypeOf(lowerer.typeOf(nameNode)))
|
|
1854
|
-
continue;
|
|
1935
|
+
? objectFactoryGlobalType(lowerer, decl.initializer) ?? undefined : undefined;
|
|
1855
1936
|
// `var p1 = import("./m")` at file scope: the global holds the
|
|
1856
1937
|
// island promise/handle — the import expression's only
|
|
1857
1938
|
// production — whatever the checker's namespace type mapped to
|
|
@@ -1865,20 +1946,39 @@ export function collectGlobals(lowerer, sf, topStmts) {
|
|
|
1865
1946
|
// exactly the local rule (uncheckedOverloadHandleCall).
|
|
1866
1947
|
(uncheckedOverloadHandleCall(lowerer, decl.initializer) ? JSVAL : null) : null)
|
|
1867
1948
|
: null;
|
|
1868
|
-
//
|
|
1869
|
-
//
|
|
1870
|
-
//
|
|
1871
|
-
const
|
|
1949
|
+
// JavaScript factory results with unmappable annotations still
|
|
1950
|
+
// need shared storage. Unannotated callable unions also use a
|
|
1951
|
+
// checked slot; mappable authored annotations keep their layout.
|
|
1952
|
+
const unannotatedCall = !decl.type && !hasJsTypeAnnotation(decl);
|
|
1953
|
+
const callSignature = (isJsSourceFile(sf) || unannotatedCall) && decl.initializer && ts.isCallExpression(decl.initializer)
|
|
1872
1954
|
? lowerer.checker.getResolvedSignature(decl.initializer) : undefined;
|
|
1873
1955
|
const callDeclaration = callSignature && lowerer.checker.signatureDeclaration(callSignature);
|
|
1956
|
+
const callType = callDeclaration && isJsSourceFile(callDeclaration.getSourceFile())
|
|
1957
|
+
? lowerer.mapTypeOf(lowerer.typeOf(nameNode)) : null;
|
|
1874
1958
|
const inferredJsCall = callDeclaration && isJsSourceFile(callDeclaration.getSourceFile()) &&
|
|
1875
|
-
!lowerer.
|
|
1959
|
+
(!callType || unannotatedCall && callType.kind === "union" && lowerer.unions.get(callType.unionId)?.arms.some((arm) => arm.kind === "func"));
|
|
1960
|
+
if (!factoryType && !inferredJsCall && isJsSourceFile(sf) && !lowerer.mapTypeOf(lowerer.typeOf(nameNode)))
|
|
1961
|
+
continue;
|
|
1876
1962
|
let type = handleT ?? factoryType ?? (inferredJsCall ? DYN : lowerer.irTypeOf(nameNode));
|
|
1877
1963
|
if (isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) && decl.initializer &&
|
|
1878
1964
|
(ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer)) &&
|
|
1879
1965
|
!decl.initializer.typeParameters?.length) {
|
|
1880
1966
|
type = lowerer.lambdaSignature(decl.initializer).funcType;
|
|
1881
1967
|
}
|
|
1968
|
+
// Namespace aliases of inferred helpers carry the helper's
|
|
1969
|
+
// settled callable, whose return can differ from checker inference.
|
|
1970
|
+
// Keep a shared checked slot before any consumer specializes it.
|
|
1971
|
+
if (isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) && type.kind === "func" &&
|
|
1972
|
+
decl.initializer && ts.isPropertyAccessExpression(decl.initializer)) {
|
|
1973
|
+
const member = nsMemberIdentOf(lowerer, decl.initializer);
|
|
1974
|
+
if (member && lowerer.genericFnOf(member)?.implicitParams)
|
|
1975
|
+
type = DYN;
|
|
1976
|
+
else if (member) {
|
|
1977
|
+
const source = lowerer.globalOf(member);
|
|
1978
|
+
if (source?.type.kind === "func")
|
|
1979
|
+
type = source.type;
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1882
1982
|
if (isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) &&
|
|
1883
1983
|
decl.initializer && ts.isCallExpression(decl.initializer) && type.kind === "union") {
|
|
1884
1984
|
const arms = lowerer.unions.get(type.unionId)?.arms;
|
|
@@ -1892,8 +1992,7 @@ export function collectGlobals(lowerer, sf, topStmts) {
|
|
|
1892
1992
|
// Calls through checked function values retain their object
|
|
1893
1993
|
// identity, including symbol keys absent from inferred records.
|
|
1894
1994
|
if (isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) && type.kind === "record" &&
|
|
1895
|
-
decl.initializer && ts.isCallExpression(decl.initializer) &&
|
|
1896
|
-
ts.isIdentifier(decl.initializer.expression) && lowerer.globalOf(decl.initializer.expression)?.type.kind === "dyn") {
|
|
1995
|
+
decl.initializer && ts.isCallExpression(decl.initializer) && lowerer.dynConvertible(type)) {
|
|
1897
1996
|
type = DYN;
|
|
1898
1997
|
}
|
|
1899
1998
|
if (isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) && type.kind === "record" &&
|
|
@@ -1916,6 +2015,10 @@ export function collectGlobals(lowerer, sf, topStmts) {
|
|
|
1916
2015
|
if (isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) && type.kind === "array" &&
|
|
1917
2016
|
decl.initializer && ts.isCallExpression(decl.initializer))
|
|
1918
2017
|
type = DYN;
|
|
2018
|
+
if (!lowerer.dynamic && isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) &&
|
|
2019
|
+
decl.initializer && ts.isNewExpression(decl.initializer) && lowerer.isStdlibGlobal(decl.initializer.expression, "Array") &&
|
|
2020
|
+
(type.kind !== "array" || type.elem.kind === "dyn"))
|
|
2021
|
+
type = DYN;
|
|
1919
2022
|
// Unannotated JavaScript aliases retain an existing native
|
|
1920
2023
|
// checked object instead of copying it into an inferred record.
|
|
1921
2024
|
if (isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) &&
|
|
@@ -2417,7 +2520,7 @@ export function lowerFileInit(lowerer, sf, stmts, name) {
|
|
|
2417
2520
|
// SITE's position instead (below) — their inner class node may
|
|
2418
2521
|
// even live in another file.
|
|
2419
2522
|
c.decl && ts.isClassDeclaration(c.decl) && !c.mixinInstance && c.decl.getSourceFile() === sf &&
|
|
2420
|
-
(c.callableBase !== undefined || c.def.baseValueGlobal !== undefined || c.staticFields.length > 0 || (c.staticBlocks?.length ?? 0) > 0 || c.classDecorators !== undefined))
|
|
2523
|
+
(c.callableBase !== undefined || c.def.baseValueGlobal !== undefined || c.runtimeStatics !== undefined || c.staticFields.length > 0 || (c.staticBlocks?.length ?? 0) > 0 || c.classDecorators !== undefined))
|
|
2421
2524
|
.map((c) => ({ pos: c.decl.getStart(), info: c }));
|
|
2422
2525
|
// Statics-bearing MIXIN instantiations whose call evaluates in THIS
|
|
2423
2526
|
// file: their declaration-time code runs when the call does — the
|
|
@@ -2443,7 +2546,8 @@ export function lowerFileInit(lowerer, sf, stmts, name) {
|
|
|
2443
2546
|
body.push(...lowerer.lowerStaticFieldInits(statics[at].info));
|
|
2444
2547
|
at++;
|
|
2445
2548
|
}
|
|
2446
|
-
const
|
|
2549
|
+
const deferred = lowerer.deferredModuleInitializers?.defer(lowerer, stmt);
|
|
2550
|
+
const stmtIr = deferred ? [deferred] : lowerer.lowerStmts([stmt]);
|
|
2447
2551
|
// Class EXPRESSIONS inside this statement queued their static
|
|
2448
2552
|
// inits while it lowered: they land immediately before it — JS's
|
|
2449
2553
|
// order for the supported whole-initializer positions.
|