@amxts/core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -23
- package/README.ru.md +19 -22
- package/as/amxts.d.ts +63 -3
- package/as/constants.ts +684 -116
- package/as/entities.ts +1905 -1364
- package/as/events.ts +1694 -905
- package/as/facade.ts +1240 -220
- package/as/fetch.ts +1519 -0
- package/as/flags.ts +159 -145
- package/as/hlds.ts +1071 -0
- package/as/hooks.ts +5226 -5379
- package/as/kit.ts +15 -5
- package/as/lib/check.ts +1 -1
- package/as/natives.ts +2658 -2499
- package/as/remote.ts +39 -15
- package/as/tsconfig.json +6 -2
- package/as/vector.ts +12 -9
- package/includes/order.txt +22 -29
- package/includes/sources.json +0 -8
- package/node_modules/assemblyscript/std/assembly/index.d.ts +20 -11
- package/package.json +29 -7
- package/runtime/deps/assemblyscript/dist/asc.js +86 -16
- package/runtime/deps/assemblyscript/dist/assemblyscript.js +29 -29
- package/runtime/licenses/MPL-2.0.txt +373 -0
- package/runtime/licenses/README.md +5 -1
- package/runtime/licenses/curl-COPYING +22 -0
- package/runtime/licenses/libssh2-COPYING +43 -0
- package/runtime/licenses/mbedTLS-LICENSE +553 -0
- package/runtime/natives.txt +108 -105
- package/runtime/patches/assemblyscript-0.28.20-amxts.patch +752 -296
- package/runtime/patches/wamr-2.4.5-amxts.patch +148 -0
- package/scripts/apply-docs.ts +2 -2
- package/scripts/auto-imports.ts +2 -2
- package/scripts/build-identity.ts +115 -0
- package/scripts/build-wasm.ts +101 -50
- package/scripts/check.ts +17 -3
- package/scripts/client-messages.ts +246 -0
- package/scripts/compile-pool.ts +128 -0
- package/scripts/compile-worker.ts +23 -0
- package/scripts/compile.ts +156 -59
- package/scripts/docker-server.ts +13 -3
- package/scripts/docs/as/amxts.ts +86 -0
- package/scripts/docs/as/facade.ts +688 -188
- package/scripts/docs/as/fetch.ts +805 -0
- package/scripts/docs/entities.ts +43 -144
- package/scripts/docs/events.ts +15 -26
- package/scripts/docs/game.ts +68 -22
- package/scripts/docs/messages.ts +330 -16
- package/scripts/editor-api.ts +101 -0
- package/scripts/hlds-events.ts +370 -0
- package/scripts/includes.ts +12 -10
- package/scripts/player-fields.ts +16 -15
- package/scripts/prebuilt.ts +65 -23
- package/scripts/prepare.ts +39 -28
- package/scripts/project.ts +120 -20
- package/scripts/reapi-events.ts +98 -0
- package/scripts/shared-modules.ts +85 -23
- package/scripts/source-map.ts +242 -0
- package/scripts/system.ts +1 -1
- package/scripts/typed-commands.ts +263 -0
- package/scripts/typed-configs.ts +23 -12
- package/scripts/ui.ts +3 -1
- package/scripts/upgrade-menus.ts +274 -0
- package/scripts/upgrade-names.ts +384 -0
- package/scripts/upgrade.ts +830 -0
- package/src/cli-api.mjs +37 -4
- package/src/system.mjs +74 -3
- package/src/testing/compile.ts +8 -5
- package/src/testing/natives.ts +199 -5
- package/src/testing/network.ts +531 -0
- package/src/testing/server.ts +565 -47
- package/src/testing/tables.ts +25 -0
- package/as/modules/http.ts +0 -184
- package/scripts/docs/as/modules/http.ts +0 -66
|
@@ -378,7 +378,7 @@ index f876049..8d02018 100644
|
|
|
378
378
|
function builtin_isArray(ctx: BuiltinFunctionContext): ExpressionRef {
|
|
379
379
|
let compiler = ctx.compiler;
|
|
380
380
|
diff --git a/src/compiler.ts b/src/compiler.ts
|
|
381
|
-
index f99bd5a..
|
|
381
|
+
index f99bd5a..282aa0e 100644
|
|
382
382
|
--- a/src/compiler.ts
|
|
383
383
|
+++ b/src/compiler.ts
|
|
384
384
|
@@ -49,6 +49,7 @@ import {
|
|
@@ -499,7 +499,15 @@ index f99bd5a..d9c1b77 100644
|
|
|
499
499
|
|
|
500
500
|
// Error if there's neither a type nor an initializer
|
|
501
501
|
} else {
|
|
502
|
-
@@ -
|
|
502
|
+
@@ -1412,6 +1442,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
let internalName = global.internalName;
|
|
506
|
+
+ if (this.earlyGlobals.has(global)) module.removeGlobal(internalName); // amxts: its stand-in
|
|
507
|
+
|
|
508
|
+
if (initializeInStart) { // initialize to mutable zero and set the actual value in start
|
|
509
|
+
if (isDeclaredInline) {
|
|
510
|
+
@@ -1434,10 +1465,76 @@ export class Compiler extends DiagnosticEmitter {
|
|
503
511
|
} else if (!isDeclaredInline) { // compile normally
|
|
504
512
|
module.addGlobal(internalName, typeRef, !isDeclaredConstant, initExpr);
|
|
505
513
|
}
|
|
@@ -539,6 +547,15 @@ index f99bd5a..d9c1b77 100644
|
|
|
539
547
|
+ }
|
|
540
548
|
+
|
|
541
549
|
+ /**
|
|
550
|
+
+ * amxts: the globals read or written above their declaration before it was
|
|
551
|
+
+ * compiled. Binaryen looks a global up when it weighs an expression that
|
|
552
|
+
+ * reads it - as an indirect call does the function it calls, `STEPS[i]()` -
|
|
553
|
+
+ * so each has a stand-in in the module from its first such use, which
|
|
554
|
+
+ * compileGlobal replaces with the global itself.
|
|
555
|
+
+ */
|
|
556
|
+
+ private earlyGlobals: Set<Global> = new Set();
|
|
557
|
+
+
|
|
558
|
+
+ /**
|
|
542
559
|
+ * amxts: `expr`, a read or write of `global`, after a check that its
|
|
543
560
|
+ * declaration has run - JavaScript's ReferenceError in the temporal dead
|
|
544
561
|
+ * zone: an abort that says so and ends the current call. The flag it
|
|
@@ -546,6 +563,10 @@ index f99bd5a..d9c1b77 100644
|
|
|
546
563
|
+ */
|
|
547
564
|
+ private makeGlobalTdzCheck(global: Global, expr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef {
|
|
548
565
|
+ let module = this.module;
|
|
566
|
+
+ if ((!global.is(CommonFlags.Compiled) || this.pendingElements.has(global)) && !this.earlyGlobals.has(global)) {
|
|
567
|
+
+ this.earlyGlobals.add(global);
|
|
568
|
+
+ module.addGlobal(global.internalName, global.type.toRef(), true, this.makeZero(global.type));
|
|
569
|
+
+ }
|
|
549
570
|
+ let flag = global.tdzFlag;
|
|
550
571
|
+ if (!flag) {
|
|
551
572
|
+ global.tdzFlag = flag = global.internalName + "~initialized";
|
|
@@ -563,7 +584,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
563
584
|
// === Enums ====================================================================================
|
|
564
585
|
|
|
565
586
|
/** Compiles an enum. */
|
|
566
|
-
@@ -1684,6 +
|
|
587
|
+
@@ -1684,6 +1781,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
567
588
|
}
|
|
568
589
|
|
|
569
590
|
this.currentFlow = previousFlow;
|
|
@@ -571,7 +592,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
571
592
|
|
|
572
593
|
// create the function
|
|
573
594
|
funcRef = module.addFunction(
|
|
574
|
-
@@ -1798,9 +
|
|
595
|
+
@@ -1798,9 +1896,52 @@ export class Compiler extends DiagnosticEmitter {
|
|
575
596
|
: null;
|
|
576
597
|
let bodyStartIndex = stmts.length;
|
|
577
598
|
|
|
@@ -624,7 +645,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
624
645
|
} else {
|
|
625
646
|
// must be an expression statement if not a block
|
|
626
647
|
assert(bodyNode.kind == NodeKind.Expression);
|
|
627
|
-
@@ -1841,6 +
|
|
648
|
+
@@ -1841,6 +1982,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
628
649
|
allocStmts.push(
|
|
629
650
|
this.makeConditionalAllocation(classInstance, thisLocal.index)
|
|
630
651
|
);
|
|
@@ -634,7 +655,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
634
655
|
this.makeFieldInitializationInConstructor(classInstance, allocStmts);
|
|
635
656
|
|
|
636
657
|
// Insert right before the body
|
|
637
|
-
@@ -1876,8 +
|
|
658
|
+
@@ -1876,8 +2020,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
638
659
|
flow.set(FlowFlags.Returns | FlowFlags.ReturnsNonNull | FlowFlags.Terminates);
|
|
639
660
|
}
|
|
640
661
|
|
|
@@ -646,7 +667,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
646
667
|
this.error(
|
|
647
668
|
DiagnosticCode.Constructors_for_derived_classes_must_contain_a_super_call,
|
|
648
669
|
instance.prototype.declaration.range
|
|
649
|
-
@@ -1893,9 +
|
|
670
|
+
@@ -1893,9 +2038,67 @@ export class Compiler extends DiagnosticEmitter {
|
|
650
671
|
return false; // not recoverable
|
|
651
672
|
}
|
|
652
673
|
|
|
@@ -714,7 +735,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
714
735
|
/** Makes a built-in getter of a property that is a field. */
|
|
715
736
|
private makeBuiltinFieldGetter(property: Property): FunctionRef {
|
|
716
737
|
let getterInstance = assert(property.getterInstance);
|
|
717
|
-
@@ -2363,7 +
|
|
738
|
+
@@ -2363,7 +2566,10 @@ export class Compiler extends DiagnosticEmitter {
|
|
718
739
|
stmts.length = 0;
|
|
719
740
|
}
|
|
720
741
|
let flow = this.currentFlow;
|
|
@@ -725,7 +746,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
725
746
|
let stmt = this.compileStatement(statements[i]);
|
|
726
747
|
switch (getExpressionId(stmt)) {
|
|
727
748
|
case ExpressionId.Block: {
|
|
728
|
-
@@ -2418,16 +
|
|
749
|
+
@@ -2418,16 +2624,17 @@ export class Compiler extends DiagnosticEmitter {
|
|
729
750
|
): ExpressionRef {
|
|
730
751
|
let module = this.module;
|
|
731
752
|
let labelNode = statement.label;
|
|
@@ -751,7 +772,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
751
772
|
if (breakLabel == null) {
|
|
752
773
|
this.error(
|
|
753
774
|
DiagnosticCode.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement,
|
|
754
|
-
@@ -2436,7 +
|
|
775
|
+
@@ -2436,7 +2643,11 @@ export class Compiler extends DiagnosticEmitter {
|
|
755
776
|
return module.unreachable();
|
|
756
777
|
}
|
|
757
778
|
flow.set(FlowFlags.Breaks);
|
|
@@ -764,7 +785,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
764
785
|
}
|
|
765
786
|
|
|
766
787
|
private compileContinueStatement(
|
|
767
|
-
@@ -2444,17 +
|
|
788
|
+
@@ -2444,17 +2655,18 @@ export class Compiler extends DiagnosticEmitter {
|
|
768
789
|
): ExpressionRef {
|
|
769
790
|
let module = this.module;
|
|
770
791
|
let label = statement.label;
|
|
@@ -791,7 +812,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
791
812
|
if (continueLabel == null) {
|
|
792
813
|
this.error(
|
|
793
814
|
DiagnosticCode.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement,
|
|
794
|
-
@@ -2463,7 +
|
|
815
|
+
@@ -2463,7 +2675,11 @@ export class Compiler extends DiagnosticEmitter {
|
|
795
816
|
return module.unreachable();
|
|
796
817
|
}
|
|
797
818
|
flow.set(FlowFlags.Continues | FlowFlags.Terminates);
|
|
@@ -804,7 +825,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
804
825
|
}
|
|
805
826
|
|
|
806
827
|
private compileDoStatement(
|
|
807
|
-
@@ -2504,6 +
|
|
828
|
+
@@ -2504,6 +2720,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
808
829
|
flow.continueLabel = continueLabel;
|
|
809
830
|
let loopLabel = `do-loop|${label}`;
|
|
810
831
|
this.currentFlow = flow;
|
|
@@ -812,7 +833,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
812
833
|
let bodyStmts = new Array<ExpressionRef>();
|
|
813
834
|
let body = statement.body;
|
|
814
835
|
if (body.kind == NodeKind.Block) {
|
|
815
|
-
@@ -2511,6 +
|
|
836
|
+
@@ -2511,6 +2728,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
816
837
|
} else {
|
|
817
838
|
bodyStmts.push(this.compileStatement(body));
|
|
818
839
|
}
|
|
@@ -820,7 +841,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
820
841
|
flow.popControlFlowLabel(label);
|
|
821
842
|
|
|
822
843
|
let possiblyContinues = flow.isAny(FlowFlags.Continues | FlowFlags.ConditionallyContinues);
|
|
823
|
-
@@ -2634,6 +
|
|
844
|
+
@@ -2634,6 +2852,21 @@ export class Compiler extends DiagnosticEmitter {
|
|
824
845
|
stmts.push(this.compileStatement(initializer));
|
|
825
846
|
}
|
|
826
847
|
|
|
@@ -842,7 +863,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
842
863
|
// Precompute the condition if present, or default to `true`
|
|
843
864
|
let condExpr: ExpressionRef;
|
|
844
865
|
let condExprTrueish: ExpressionRef;
|
|
845
|
-
@@ -2669,6 +
|
|
866
|
+
@@ -2669,6 +2902,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
846
867
|
bodyFlow.continueLabel = continueLabel;
|
|
847
868
|
let loopLabel = `for-loop|${label}`;
|
|
848
869
|
this.currentFlow = bodyFlow;
|
|
@@ -850,7 +871,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
850
871
|
let bodyStmts = new Array<ExpressionRef>();
|
|
851
872
|
let body = statement.body;
|
|
852
873
|
if (body.kind == NodeKind.Block) {
|
|
853
|
-
@@ -2676,6 +
|
|
874
|
+
@@ -2676,6 +2910,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
854
875
|
} else {
|
|
855
876
|
bodyStmts.push(this.compileStatement(body));
|
|
856
877
|
}
|
|
@@ -858,7 +879,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
858
879
|
bodyFlow.popControlFlowLabel(label);
|
|
859
880
|
bodyFlow.breakLabel = null;
|
|
860
881
|
bodyFlow.continueLabel = null;
|
|
861
|
-
@@ -2700,6 +
|
|
882
|
+
@@ -2700,6 +2935,19 @@ export class Compiler extends DiagnosticEmitter {
|
|
862
883
|
// Compile the incrementor if it possibly executes
|
|
863
884
|
let possiblyLoops = possiblyContinues || possiblyFallsThrough;
|
|
864
885
|
if (possiblyLoops) {
|
|
@@ -878,7 +899,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
878
899
|
let incrementor = statement.incrementor;
|
|
879
900
|
if (incrementor) {
|
|
880
901
|
this.currentFlow = flow;
|
|
881
|
-
@@ -2802,6 +
|
|
902
|
+
@@ -2802,6 +3050,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
882
903
|
// Compile ifTrue assuming the condition turned out true
|
|
883
904
|
let thenStmts = new Array<ExpressionRef>();
|
|
884
905
|
let thenFlow = flow.forkThen(condExpr);
|
|
@@ -886,7 +907,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
886
907
|
this.currentFlow = thenFlow;
|
|
887
908
|
if (ifTrue.kind == NodeKind.Block) {
|
|
888
909
|
this.compileStatements((<BlockStatement>ifTrue).statements, thenStmts);
|
|
889
|
-
@@ -2812,6 +
|
|
910
|
+
@@ -2812,6 +3061,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
890
911
|
|
|
891
912
|
// Compile ifFalse assuming the condition turned out false, if present
|
|
892
913
|
let elseFlow = flow.forkElse(condExpr);
|
|
@@ -894,7 +915,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
894
915
|
if (ifFalse) {
|
|
895
916
|
this.currentFlow = elseFlow;
|
|
896
917
|
let elseStmts = new Array<ExpressionRef>();
|
|
897
|
-
@@ -2850,6 +
|
|
918
|
+
@@ -2850,6 +3100,14 @@ export class Compiler extends DiagnosticEmitter {
|
|
898
919
|
let flow = this.currentFlow;
|
|
899
920
|
let returnType = flow.returnType;
|
|
900
921
|
|
|
@@ -909,7 +930,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
909
930
|
let valueExpression = statement.value;
|
|
910
931
|
if (valueExpression) {
|
|
911
932
|
let constraints = Constraints.ConvImplicit;
|
|
912
|
-
@@ -2861,6 +
|
|
933
|
+
@@ -2861,6 +3119,19 @@ export class Compiler extends DiagnosticEmitter {
|
|
913
934
|
if (flow.sourceFunction.is(CommonFlags.Constructor) && valueExpression.kind != NodeKind.This) {
|
|
914
935
|
flow.set(FlowFlags.MayReturnNonThis);
|
|
915
936
|
}
|
|
@@ -929,7 +950,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
929
950
|
} else if (returnType != Type.void) {
|
|
930
951
|
this.error(
|
|
931
952
|
DiagnosticCode.Type_0_is_not_assignable_to_type_1,
|
|
932
|
-
@@ -2868,27 +
|
|
953
|
+
@@ -2868,27 +3139,33 @@ export class Compiler extends DiagnosticEmitter {
|
|
933
954
|
);
|
|
934
955
|
this.currentType = returnType;
|
|
935
956
|
return module.unreachable();
|
|
@@ -971,7 +992,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
971
992
|
}
|
|
972
993
|
|
|
973
994
|
private compileSwitchStatement(
|
|
974
|
-
@@ -3018,12 +
|
|
995
|
+
@@ -3018,12 +3295,51 @@ export class Compiler extends DiagnosticEmitter {
|
|
975
996
|
private compileThrowStatement(
|
|
976
997
|
statement: ThrowStatement
|
|
977
998
|
): ExpressionRef {
|
|
@@ -1013,6 +1034,8 @@ index f99bd5a..d9c1b77 100644
|
|
|
1013
1034
|
+ module.i32(source.lineAt(statement.range.start)),
|
|
1014
1035
|
+ module.i32(source.columnAt())
|
|
1015
1036
|
+ ], TypeRef.I32);
|
|
1037
|
+
+ // amxts: a failed call's stack stops at this call - its place, in the source map
|
|
1038
|
+
+ if (this.options.sourceMap) this.addDebugLocation(thrown, statement.range);
|
|
1016
1039
|
+ this.currentType = Type.void;
|
|
1017
1040
|
+ return this.unwindsIn(target)
|
|
1018
1041
|
+ ? module.block(null, [ module.if(thrown, this.makeUnwind()), module.unreachable() ])
|
|
@@ -1022,7 +1045,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1022
1045
|
let stmts = new Array<ExpressionRef>();
|
|
1023
1046
|
let value = statement.value;
|
|
1024
1047
|
let message: Expression | null = null;
|
|
1025
|
-
@@ -3037,17 +
|
|
1048
|
+
@@ -3037,17 +3353,685 @@ export class Compiler extends DiagnosticEmitter {
|
|
1026
1049
|
return this.module.flatten(stmts);
|
|
1027
1050
|
}
|
|
1028
1051
|
|
|
@@ -1714,14 +1737,10 @@ index f99bd5a..d9c1b77 100644
|
|
|
1714
1737
|
}
|
|
1715
1738
|
|
|
1716
1739
|
/** Compiles a variable statement. Returns `0` if an initializer is not necessary. */
|
|
1717
|
-
@@ -3078,
|
|
1740
|
+
@@ -3078,6 +4062,32 @@ export class Compiler extends DiagnosticEmitter {
|
|
1718
1741
|
// Resolve type if annotated
|
|
1719
1742
|
let typeNode = declaration.type;
|
|
1720
1743
|
let initializerNode = declaration.initializer;
|
|
1721
|
-
- if (typeNode) {
|
|
1722
|
-
- type = resolver.resolveType( // reports
|
|
1723
|
-
- typeNode, flow,
|
|
1724
|
-
- flow.sourceFunction,
|
|
1725
1744
|
+ // amxts: one a hoisted function uses has its box already - see hoistFunctions.
|
|
1726
1745
|
+ let predeclared = flow.getScopedLocal(name);
|
|
1727
1746
|
+ if (predeclared && predeclared.closurePredeclared) {
|
|
@@ -1748,14 +1767,10 @@ index f99bd5a..d9c1b77 100644
|
|
|
1748
1767
|
+ continue;
|
|
1749
1768
|
+ }
|
|
1750
1769
|
+ }
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
+
|
|
1755
|
-
cloneMap(flow.contextualTypeArguments)
|
|
1756
|
-
);
|
|
1757
|
-
if (!type) continue;
|
|
1758
|
-
@@ -3238,7 +4232,31 @@ export class Compiler extends DiagnosticEmitter {
|
|
1770
|
+
if (typeNode) {
|
|
1771
|
+
type = resolver.resolveType( // reports
|
|
1772
|
+
typeNode, flow,
|
|
1773
|
+
@@ -3238,7 +4248,31 @@ export class Compiler extends DiagnosticEmitter {
|
|
1759
1774
|
flow.unsetLocalFlag(local.index, ~0);
|
|
1760
1775
|
if (isConst) flow.setLocalFlag(local.index, LocalFlags.Constant);
|
|
1761
1776
|
}
|
|
@@ -1788,7 +1803,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1788
1803
|
initializers.push(
|
|
1789
1804
|
this.makeLocalAssignment(local, initExpr, initType ? initType : type, false)
|
|
1790
1805
|
);
|
|
1791
|
-
@@ -3312,6 +
|
|
1806
|
+
@@ -3312,6 +4346,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
1792
1807
|
let continueLabel = `while-continue|${label}`;
|
|
1793
1808
|
thenFlow.continueLabel = continueLabel;
|
|
1794
1809
|
this.currentFlow = thenFlow;
|
|
@@ -1796,7 +1811,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1796
1811
|
let bodyStmts = new Array<ExpressionRef>();
|
|
1797
1812
|
let body = statement.body;
|
|
1798
1813
|
if (body.kind == NodeKind.Block) {
|
|
1799
|
-
@@ -3319,6 +
|
|
1814
|
+
@@ -3319,6 +4354,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
1800
1815
|
} else {
|
|
1801
1816
|
bodyStmts.push(this.compileStatement(body));
|
|
1802
1817
|
}
|
|
@@ -1804,7 +1819,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1804
1819
|
bodyStmts.push(
|
|
1805
1820
|
module.br(continueLabel)
|
|
1806
1821
|
);
|
|
1807
|
-
@@ -3479,6 +
|
|
1822
|
+
@@ -3479,6 +4515,11 @@ export class Compiler extends DiagnosticEmitter {
|
|
1808
1823
|
break;
|
|
1809
1824
|
}
|
|
1810
1825
|
case NodeKind.Call: {
|
|
@@ -1816,7 +1831,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1816
1831
|
expr = this.compileCallExpression(<CallExpression>expression, contextualType, constraints);
|
|
1817
1832
|
break;
|
|
1818
1833
|
}
|
|
1819
|
-
@@ -3487,6 +
|
|
1834
|
+
@@ -3487,6 +4528,10 @@ export class Compiler extends DiagnosticEmitter {
|
|
1820
1835
|
break;
|
|
1821
1836
|
}
|
|
1822
1837
|
case NodeKind.ElementAccess: {
|
|
@@ -1827,7 +1842,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1827
1842
|
expr = this.compileElementAccessExpression(<ElementAccessExpression>expression, contextualType, constraints);
|
|
1828
1843
|
break;
|
|
1829
1844
|
}
|
|
1830
|
-
@@ -3516,6 +
|
|
1845
|
+
@@ -3516,6 +4561,10 @@ export class Compiler extends DiagnosticEmitter {
|
|
1831
1846
|
break;
|
|
1832
1847
|
}
|
|
1833
1848
|
case NodeKind.PropertyAccess: {
|
|
@@ -1838,7 +1853,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1838
1853
|
expr = this.compilePropertyAccessExpression(<PropertyAccessExpression>expression, contextualType, constraints);
|
|
1839
1854
|
break;
|
|
1840
1855
|
}
|
|
1841
|
-
@@ -3571,6 +
|
|
1856
|
+
@@ -3571,6 +4620,20 @@ export class Compiler extends DiagnosticEmitter {
|
|
1842
1857
|
return expr;
|
|
1843
1858
|
}
|
|
1844
1859
|
|
|
@@ -1859,7 +1874,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1859
1874
|
/** Converts an expression's result from one type to another. */
|
|
1860
1875
|
convertExpression(
|
|
1861
1876
|
expr: ExpressionRef,
|
|
1862
|
-
@@ -3602,10 +
|
|
1877
|
+
@@ -3602,10 +4665,46 @@ export class Compiler extends DiagnosticEmitter {
|
|
1863
1878
|
// any to void
|
|
1864
1879
|
if (toType.kind == TypeKind.Void) return module.drop(expr);
|
|
1865
1880
|
|
|
@@ -1906,7 +1921,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1906
1921
|
} else if (explicit && fromType.isNullableReference && !toType.isNullableReference) {
|
|
1907
1922
|
// explicit conversion from nullable to non-nullable requires a runtime
|
|
1908
1923
|
// check here because nonnull state above already didn't know better
|
|
1909
|
-
@@ -3614,7 +
|
|
1924
|
+
@@ -3614,7 +4713,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
1910
1925
|
}
|
|
1911
1926
|
fromType = fromType.nonNullableType;
|
|
1912
1927
|
}
|
|
@@ -1915,7 +1930,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1915
1930
|
assert(toType.isExternalReference || fromType.kind == toType.kind);
|
|
1916
1931
|
this.currentType = toType;
|
|
1917
1932
|
return expr;
|
|
1918
|
-
@@ -3670,7 +
|
|
1933
|
+
@@ -3670,7 +4769,26 @@ export class Compiler extends DiagnosticEmitter {
|
|
1919
1934
|
return module.unreachable();
|
|
1920
1935
|
}
|
|
1921
1936
|
|
|
@@ -1943,7 +1958,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1943
1958
|
if (!explicit) {
|
|
1944
1959
|
this.error(
|
|
1945
1960
|
DiagnosticCode.Conversion_from_type_0_to_1_requires_an_explicit_cast,
|
|
1946
|
-
@@ -3845,10 +
|
|
1961
|
+
@@ -3845,10 +4963,14 @@ export class Compiler extends DiagnosticEmitter {
|
|
1947
1962
|
let expr = this.compileExpression(expression.expression, contextualType.exceptVoid, inheritedConstraints);
|
|
1948
1963
|
let type = this.currentType;
|
|
1949
1964
|
if (this.currentFlow.isNonnull(expr, type)) {
|
|
@@ -1962,7 +1977,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1962
1977
|
} else if (!this.options.noAssert) {
|
|
1963
1978
|
expr = this.makeRuntimeNonNullCheck(expr, type, expression);
|
|
1964
1979
|
}
|
|
1965
|
-
@@ -3893,6 +
|
|
1980
|
+
@@ -3893,6 +5015,10 @@ export class Compiler extends DiagnosticEmitter {
|
|
1966
1981
|
contextualType: Type,
|
|
1967
1982
|
): ExpressionRef {
|
|
1968
1983
|
|
|
@@ -1973,7 +1988,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1973
1988
|
const left = expression.left;
|
|
1974
1989
|
const leftExpr = this.compileExpression(left, contextualType);
|
|
1975
1990
|
const leftType = this.currentType;
|
|
1976
|
-
@@ -4109,6 +
|
|
1991
|
+
@@ -4109,6 +5235,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
1977
1992
|
}
|
|
1978
1993
|
case Token.Plus_Equals: compound = true;
|
|
1979
1994
|
case Token.Plus: {
|
|
@@ -1987,7 +2002,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1987
2002
|
leftExpr = this.compileExpression(left, contextualType);
|
|
1988
2003
|
leftType = this.currentType;
|
|
1989
2004
|
|
|
1990
|
-
@@ -4315,6 +
|
|
2005
|
+
@@ -4315,6 +5448,11 @@ export class Compiler extends DiagnosticEmitter {
|
|
1991
2006
|
rightExpr = this.compileExpression(right, leftType);
|
|
1992
2007
|
rightType = this.currentType;
|
|
1993
2008
|
commonType = Type.commonType(leftType, rightType, contextualType);
|
|
@@ -1999,7 +2014,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
1999
2014
|
if (!commonType || !commonType.isNumericValue) {
|
|
2000
2015
|
this.error(
|
|
2001
2016
|
DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,
|
|
2002
|
-
@@ -4390,6 +
|
|
2017
|
+
@@ -4390,6 +5528,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
2003
2018
|
break;
|
|
2004
2019
|
}
|
|
2005
2020
|
}
|
|
@@ -2013,7 +2028,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2013
2028
|
if (!leftType.isIntegerValue) {
|
|
2014
2029
|
this.error(
|
|
2015
2030
|
DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,
|
|
2016
|
-
@@ -4417,6 +
|
|
2031
|
+
@@ -4417,6 +5562,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
2017
2032
|
break;
|
|
2018
2033
|
}
|
|
2019
2034
|
}
|
|
@@ -2027,7 +2042,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2027
2042
|
if (!leftType.isIntegerValue) {
|
|
2028
2043
|
this.error(
|
|
2029
2044
|
DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,
|
|
2030
|
-
@@ -4445,6 +
|
|
2045
|
+
@@ -4445,6 +5597,12 @@ export class Compiler extends DiagnosticEmitter {
|
|
2031
2046
|
break;
|
|
2032
2047
|
}
|
|
2033
2048
|
}
|
|
@@ -2040,7 +2055,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2040
2055
|
if (!leftType.isIntegerValue) {
|
|
2041
2056
|
this.error(
|
|
2042
2057
|
DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,
|
|
2043
|
-
@@ -4473,6 +
|
|
2058
|
+
@@ -4473,6 +5631,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
2044
2059
|
}
|
|
2045
2060
|
}
|
|
2046
2061
|
|
|
@@ -2054,7 +2069,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2054
2069
|
if (compound) {
|
|
2055
2070
|
if (!leftType.isIntegerValue) {
|
|
2056
2071
|
this.error(
|
|
2057
|
-
@@ -4486,6 +
|
|
2072
|
+
@@ -4486,6 +5651,10 @@ export class Compiler extends DiagnosticEmitter {
|
|
2058
2073
|
} else {
|
|
2059
2074
|
rightExpr = this.compileExpression(right, leftType);
|
|
2060
2075
|
rightType = this.currentType;
|
|
@@ -2065,7 +2080,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2065
2080
|
commonType = Type.commonType(leftType, rightType, contextualType);
|
|
2066
2081
|
if (!commonType || !commonType.isIntegerValue) {
|
|
2067
2082
|
this.error(
|
|
2068
|
-
@@ -4518,6 +
|
|
2083
|
+
@@ -4518,6 +5687,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
2069
2084
|
}
|
|
2070
2085
|
}
|
|
2071
2086
|
|
|
@@ -2079,7 +2094,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2079
2094
|
if (compound) {
|
|
2080
2095
|
if (!leftType.isIntegerValue) {
|
|
2081
2096
|
this.error(
|
|
2082
|
-
@@ -4531,6 +
|
|
2097
|
+
@@ -4531,6 +5707,10 @@ export class Compiler extends DiagnosticEmitter {
|
|
2083
2098
|
} else {
|
|
2084
2099
|
rightExpr = this.compileExpression(right, leftType);
|
|
2085
2100
|
rightType = this.currentType;
|
|
@@ -2090,7 +2105,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2090
2105
|
commonType = Type.commonType(leftType, rightType, contextualType);
|
|
2091
2106
|
if (!commonType || !commonType.isIntegerValue) {
|
|
2092
2107
|
this.error(
|
|
2093
|
-
@@ -4563,6 +
|
|
2108
|
+
@@ -4563,6 +5743,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
2094
2109
|
}
|
|
2095
2110
|
}
|
|
2096
2111
|
|
|
@@ -2104,7 +2119,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2104
2119
|
if (compound) {
|
|
2105
2120
|
if (!leftType.isIntegerValue) {
|
|
2106
2121
|
this.error(
|
|
2107
|
-
@@ -4576,6 +
|
|
2122
|
+
@@ -4576,6 +5763,10 @@ export class Compiler extends DiagnosticEmitter {
|
|
2108
2123
|
} else {
|
|
2109
2124
|
rightExpr = this.compileExpression(right, leftType);
|
|
2110
2125
|
rightType = this.currentType;
|
|
@@ -2115,7 +2130,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2115
2130
|
commonType = Type.commonType(leftType, rightType, contextualType);
|
|
2116
2131
|
if (!commonType || !commonType.isIntegerValue) {
|
|
2117
2132
|
this.error(
|
|
2118
|
-
@@ -4603,6 +
|
|
2133
|
+
@@ -4603,6 +5794,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
2119
2134
|
leftType = this.currentType;
|
|
2120
2135
|
|
|
2121
2136
|
let rightFlow = flow.forkThen(leftExpr);
|
|
@@ -2123,7 +2138,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2123
2138
|
this.currentFlow = rightFlow;
|
|
2124
2139
|
|
|
2125
2140
|
// simplify if only interested in true or false
|
|
2126
|
-
@@ -4782,13 +
|
|
2141
|
+
@@ -4782,13 +5974,160 @@ export class Compiler extends DiagnosticEmitter {
|
|
2127
2142
|
}
|
|
2128
2143
|
break;
|
|
2129
2144
|
}
|
|
@@ -2290,7 +2305,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2290
2305
|
}
|
|
2291
2306
|
default: {
|
|
2292
2307
|
assert(false);
|
|
2293
|
-
@@ -4796,12 +
|
|
2308
|
+
@@ -4796,12 +6135,31 @@ export class Compiler extends DiagnosticEmitter {
|
|
2294
2309
|
break;
|
|
2295
2310
|
}
|
|
2296
2311
|
}
|
|
@@ -2322,7 +2337,63 @@ index f99bd5a..d9c1b77 100644
|
|
|
2322
2337
|
if (!this.currentType.isStrictlyAssignableTo(targetType)) {
|
|
2323
2338
|
this.error(
|
|
2324
2339
|
DiagnosticCode.Type_0_is_not_assignable_to_type_1,
|
|
2325
|
-
@@ -
|
|
2340
|
+
@@ -5455,13 +6813,54 @@ export class Compiler extends DiagnosticEmitter {
|
|
2341
|
+
if (!instance || !this.compileFunction(instance)) {
|
|
2342
|
+
return module.unreachable();
|
|
2343
|
+
}
|
|
2344
|
+
- return this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode);
|
|
2345
|
+
+ return this.makeIntegralRem(leftExpr, rightExpr, instance, reportNode);
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
assert(false);
|
|
2349
|
+
return module.unreachable();
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
+ /**
|
|
2353
|
+
+ * amxts: `x % y` of two f64s, where a plugin's whole numbers are: two whole
|
|
2354
|
+
+ * numbers within i32 - each the same after i32.trunc_sat and back - take
|
|
2355
|
+
+ * i32's remainder, which has the dividend's sign as JavaScript's does, and
|
|
2356
|
+
+ * copysign keeps it on a zero (-4 % 2 is -0); anything else, NaN and a zero
|
|
2357
|
+
+ * divisor too, is Math.mod's. In place rather than in Math.mod: the call
|
|
2358
|
+
+ * itself was most of what a remainder cost. The top level, whose temps are
|
|
2359
|
+
+ * not the start function's own (see makeUnwindCheck), calls Math.mod.
|
|
2360
|
+
+ */
|
|
2361
|
+
+ private makeIntegralRem(leftExpr: ExpressionRef, rightExpr: ExpressionRef, mod: Function, reportNode: Node): ExpressionRef {
|
|
2362
|
+
+ let module = this.module;
|
|
2363
|
+
+ let flow = this.currentFlow;
|
|
2364
|
+
+ let name = flow.targetFunction.internalName;
|
|
2365
|
+
+ if (name.startsWith("start:") || name == BuiltinNames.start) {
|
|
2366
|
+
+ return this.makeCallDirect(mod, [ leftExpr, rightExpr ], reportNode);
|
|
2367
|
+
+ }
|
|
2368
|
+
+ let x = flow.getTempLocal(Type.f64).index;
|
|
2369
|
+
+ let y = flow.getTempLocal(Type.f64).index;
|
|
2370
|
+
+ let ix = flow.getTempLocal(Type.i32).index;
|
|
2371
|
+
+ let iy = flow.getTempLocal(Type.i32).index;
|
|
2372
|
+
+ let whole = (value: Index, int: Index): ExpressionRef => module.binary(BinaryOp.EqF64,
|
|
2373
|
+
+ module.unary(UnaryOp.ConvertI32ToF64, module.local_tee(int, module.unary(UnaryOp.TruncSatF64ToI32, module.local_get(value, TypeRef.F64)), false, TypeRef.I32)),
|
|
2374
|
+
+ module.local_get(value, TypeRef.F64)
|
|
2375
|
+
+ );
|
|
2376
|
+
+ return module.block(null, [
|
|
2377
|
+
+ module.local_set(x, leftExpr, false),
|
|
2378
|
+
+ module.local_set(y, rightExpr, false),
|
|
2379
|
+
+ module.if(
|
|
2380
|
+
+ module.binary(BinaryOp.AndI32,
|
|
2381
|
+
+ module.binary(BinaryOp.AndI32, whole(x, ix), whole(y, iy)),
|
|
2382
|
+
+ module.binary(BinaryOp.NeI32, module.local_get(iy, TypeRef.I32), module.i32(0))
|
|
2383
|
+
+ ),
|
|
2384
|
+
+ module.binary(BinaryOp.CopysignF64,
|
|
2385
|
+
+ module.unary(UnaryOp.ConvertI32ToF64, module.binary(BinaryOp.RemI32, module.local_get(ix, TypeRef.I32), module.local_get(iy, TypeRef.I32))),
|
|
2386
|
+
+ module.local_get(x, TypeRef.F64)
|
|
2387
|
+
+ ),
|
|
2388
|
+
+ this.makeCallDirect(mod, [ module.local_get(x, TypeRef.F64), module.local_get(y, TypeRef.F64) ], reportNode)
|
|
2389
|
+
+ )
|
|
2390
|
+
+ ], TypeRef.F64);
|
|
2391
|
+
+ }
|
|
2392
|
+
+
|
|
2393
|
+
makeShl(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {
|
|
2394
|
+
// Cares about garbage bits on the RHS, but only for types smaller than 5 bits
|
|
2395
|
+
let module = this.module;
|
|
2396
|
+
@@ -5683,6 +7082,166 @@ export class Compiler extends DiagnosticEmitter {
|
|
2326
2397
|
return this.makeCallDirect(operatorInstance, [ firstExpr, secondExpr ], reportNode);
|
|
2327
2398
|
}
|
|
2328
2399
|
|
|
@@ -2347,11 +2418,12 @@ index f99bd5a..d9c1b77 100644
|
|
|
2347
2418
|
+ }
|
|
2348
2419
|
+
|
|
2349
2420
|
+ /**
|
|
2350
|
-
+ * amxts: a value given where `string | (...) => string`
|
|
2351
|
-
+ * argument, an object literal's field,
|
|
2352
|
-
+ * assignment. The type is held as the function,
|
|
2353
|
-
+ * that returns it (__textFunction in
|
|
2354
|
-
+ *
|
|
2421
|
+
+ * amxts: a value given where `string | (...) => string` - or `boolean |
|
|
2422
|
+
+ * (...) => boolean` - is declared: an argument, an object literal's field,
|
|
2423
|
+
+ * a field's initializer, an assignment. The type is held as the function,
|
|
2424
|
+
+ * so a string becomes one that returns it (__textFunction in
|
|
2425
|
+
+ * std/assembly/function.ts), a boolean likewise (__boolFunction); a
|
|
2426
|
+
+ * function, or anything else, is compiled as it is.
|
|
2355
2427
|
+ */
|
|
2356
2428
|
+ private compileText(
|
|
2357
2429
|
+ value: Expression,
|
|
@@ -2385,6 +2457,14 @@ index f99bd5a..d9c1b77 100644
|
|
|
2385
2457
|
+ this.currentType = helper.signature.returnType;
|
|
2386
2458
|
+ return call;
|
|
2387
2459
|
+ }
|
|
2460
|
+
+ if (valueType == Type.bool) {
|
|
2461
|
+
+ let expr = this.compileExpression(inner, Type.bool, Constraints.ConvImplicit);
|
|
2462
|
+
+ let helper = this.asyncHood("__boolFunction", value, [ type.nonNullableType ]);
|
|
2463
|
+
+ if (!helper) return this.module.unreachable();
|
|
2464
|
+
+ let call = this.makeCallDirect(helper, [ expr ], value);
|
|
2465
|
+
+ this.currentType = helper.signature.returnType;
|
|
2466
|
+
+ return call;
|
|
2467
|
+
+ }
|
|
2388
2468
|
+ }
|
|
2389
2469
|
+ }
|
|
2390
2470
|
+ return this.compileExpression(value, type, constraints);
|
|
@@ -2480,7 +2560,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2480
2560
|
private compileAssignment(
|
|
2481
2561
|
expression: Expression,
|
|
2482
2562
|
valueExpression: Expression,
|
|
2483
|
-
@@ -5691,6 +
|
|
2563
|
+
@@ -5691,6 +7250,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
2484
2564
|
let program = this.program;
|
|
2485
2565
|
let resolver = program.resolver;
|
|
2486
2566
|
let flow = this.currentFlow;
|
|
@@ -2494,7 +2574,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2494
2574
|
let target = resolver.lookupExpression(expression, flow); // reports
|
|
2495
2575
|
if (!target) return this.module.unreachable();
|
|
2496
2576
|
let thisExpression = resolver.currentThisExpression;
|
|
2497
|
-
@@ -5698,6 +
|
|
2577
|
+
@@ -5698,6 +7264,8 @@ export class Compiler extends DiagnosticEmitter {
|
|
2498
2578
|
|
|
2499
2579
|
// to compile just the value, we need to know the target's type
|
|
2500
2580
|
let targetType: Type;
|
|
@@ -2503,7 +2583,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2503
2583
|
switch (target.kind) {
|
|
2504
2584
|
case ElementKind.Global:
|
|
2505
2585
|
case ElementKind.Local: {
|
|
2506
|
-
@@ -5705,15 +
|
|
2586
|
+
@@ -5705,15 +7273,8 @@ export class Compiler extends DiagnosticEmitter {
|
|
2507
2587
|
if (!this.compileGlobalLazy(<Global>target, expression)) {
|
|
2508
2588
|
return this.module.unreachable();
|
|
2509
2589
|
}
|
|
@@ -2520,7 +2600,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2520
2600
|
if (this.pendingElements.has(target)) {
|
|
2521
2601
|
this.error(
|
|
2522
2602
|
DiagnosticCode.Variable_0_used_before_its_declaration,
|
|
2523
|
-
@@ -5756,6 +
|
|
2603
|
+
@@ -5756,6 +7317,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
2524
2604
|
assert(setterInstance.signature.parameterTypes.length == 1); // parser must guarantee this
|
|
2525
2605
|
targetType = setterInstance.signature.parameterTypes[0];
|
|
2526
2606
|
if (setterInstance.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(expression);
|
|
@@ -2530,7 +2610,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2530
2610
|
break;
|
|
2531
2611
|
}
|
|
2532
2612
|
case ElementKind.IndexSignature: {
|
|
2533
|
-
@@ -5804,7 +
|
|
2613
|
+
@@ -5804,7 +7368,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
2534
2614
|
|
|
2535
2615
|
// compile the value and do the assignment
|
|
2536
2616
|
assert(targetType != Type.void);
|
|
@@ -2539,7 +2619,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2539
2619
|
let valueType = this.currentType;
|
|
2540
2620
|
if (targetType.isNullableReference && this.currentFlow.isNonnull(valueExpr, valueType)) targetType = targetType.nonNullableType;
|
|
2541
2621
|
return this.makeAssignment(
|
|
2542
|
-
@@ -5841,7 +
|
|
2622
|
+
@@ -5841,7 +7405,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
2543
2623
|
switch (target.kind) {
|
|
2544
2624
|
case ElementKind.Local: {
|
|
2545
2625
|
let local = <Local>target;
|
|
@@ -2550,7 +2630,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2550
2630
|
this.error(
|
|
2551
2631
|
DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,
|
|
2552
2632
|
valueExpression.range, target.internalName
|
|
2553
|
-
@@ -5849,6 +
|
|
2633
|
+
@@ -5849,6 +7415,17 @@ export class Compiler extends DiagnosticEmitter {
|
|
2554
2634
|
this.currentType = tee ? local.type : Type.void;
|
|
2555
2635
|
return module.unreachable();
|
|
2556
2636
|
}
|
|
@@ -2568,15 +2648,17 @@ index f99bd5a..d9c1b77 100644
|
|
|
2568
2648
|
return this.makeLocalAssignment(local, valueExpr, valueType, tee);
|
|
2569
2649
|
}
|
|
2570
2650
|
case ElementKind.Global: {
|
|
2571
|
-
@@ -5856,6 +
|
|
2651
|
+
@@ -5856,6 +7433,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
2572
2652
|
if (!this.compileGlobalLazy(global, valueExpression)) {
|
|
2573
2653
|
return module.unreachable();
|
|
2574
2654
|
}
|
|
2575
|
-
+ flow.forgetGlobalPaths(global.internalName); // amxts: no longer narrowed
|
|
2655
|
+
+ flow.forgetGlobalPaths(global.internalName); // amxts: no longer narrowed - or
|
|
2656
|
+
+ // narrowed by what it was given, `client = new Client()`, as TypeScript does
|
|
2657
|
+
+ if (global.type.isNullableReference && !valueType.isNullableReference) flow.setGlobalNonNull(global.internalName);
|
|
2576
2658
|
if (target.isAny(CommonFlags.Const | CommonFlags.Readonly)) {
|
|
2577
2659
|
this.error(
|
|
2578
2660
|
DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,
|
|
2579
|
-
@@ -5865,7 +
|
|
2661
|
+
@@ -5865,7 +7445,14 @@ export class Compiler extends DiagnosticEmitter {
|
|
2580
2662
|
this.currentType = tee ? global.type : Type.void;
|
|
2581
2663
|
return module.unreachable();
|
|
2582
2664
|
}
|
|
@@ -2592,7 +2674,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2592
2674
|
}
|
|
2593
2675
|
case ElementKind.PropertyPrototype: {
|
|
2594
2676
|
let propertyInstance = this.resolver.resolveProperty(<PropertyPrototype>target);
|
|
2595
|
-
@@ -5893,6 +
|
|
2677
|
+
@@ -5893,6 +7480,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
2596
2678
|
if (isConstructor && thisExpression.kind == NodeKind.This) {
|
|
2597
2679
|
flow.setThisFieldFlag(propertyInstance, FieldFlags.Initialized);
|
|
2598
2680
|
}
|
|
@@ -2602,7 +2684,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2602
2684
|
}
|
|
2603
2685
|
let setterInstance = propertyInstance.setterInstance;
|
|
2604
2686
|
if (!setterInstance) {
|
|
2605
|
-
@@ -5904,6 +
|
|
2687
|
+
@@ -5904,6 +7494,39 @@ export class Compiler extends DiagnosticEmitter {
|
|
2606
2688
|
}
|
|
2607
2689
|
assert(setterInstance.signature.parameterTypes.length == 1);
|
|
2608
2690
|
assert(setterInstance.signature.returnType == Type.void);
|
|
@@ -2642,7 +2724,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2642
2724
|
if (propertyInstance.is(CommonFlags.Instance)) {
|
|
2643
2725
|
let thisType = assert(setterInstance.signature.thisType);
|
|
2644
2726
|
let thisExpr = this.compileExpression(
|
|
2645
|
-
@@ -6028,11 +
|
|
2727
|
+
@@ -6028,11 +7651,31 @@ export class Compiler extends DiagnosticEmitter {
|
|
2646
2728
|
tee: bool
|
|
2647
2729
|
): ExpressionRef {
|
|
2648
2730
|
let module = this.module;
|
|
@@ -2675,7 +2757,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2675
2757
|
if (type.isNullableReference) {
|
|
2676
2758
|
if (!valueType.isNullableReference || flow.isNonnull(valueExpr, type)) flow.setLocalFlag(localIndex, LocalFlags.NonNull);
|
|
2677
2759
|
else flow.unsetLocalFlag(localIndex, LocalFlags.NonNull);
|
|
2678
|
-
@@ -6042,13 +
|
|
2760
|
+
@@ -6042,13 +7685,6 @@ export class Compiler extends DiagnosticEmitter {
|
|
2679
2761
|
if (!flow.canOverflow(valueExpr, type)) flow.setLocalFlag(localIndex, LocalFlags.Wrapped);
|
|
2680
2762
|
else flow.unsetLocalFlag(localIndex, LocalFlags.Wrapped);
|
|
2681
2763
|
}
|
|
@@ -2689,7 +2771,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2689
2771
|
}
|
|
2690
2772
|
|
|
2691
2773
|
/** Makes an assignment to a global. */
|
|
2692
|
-
@@ -6146,6 +
|
|
2774
|
+
@@ -6146,6 +7782,42 @@ export class Compiler extends DiagnosticEmitter {
|
|
2693
2775
|
return module.local_set(thisLocal.index, superCall, classInstance.type.isManaged);
|
|
2694
2776
|
}
|
|
2695
2777
|
|
|
@@ -2732,7 +2814,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2732
2814
|
// otherwise resolve normally
|
|
2733
2815
|
let target = this.resolver.lookupExpression(expression.expression, flow); // reports
|
|
2734
2816
|
if (!target) return module.unreachable();
|
|
2735
|
-
@@ -6443,7 +
|
|
2817
|
+
@@ -6443,7 +8115,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
2736
2818
|
// otherwise, the arguments may not be inlined, e.g. `abc(abc(123))`
|
|
2737
2819
|
let args = new Array<ExpressionRef>(numArguments);
|
|
2738
2820
|
for (let i = 0; i < numArguments; ++i) {
|
|
@@ -2741,7 +2823,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2741
2823
|
}
|
|
2742
2824
|
// make the inlined call
|
|
2743
2825
|
inlineStack.push(instance);
|
|
2744
|
-
@@ -6464,7 +
|
|
2826
|
+
@@ -6464,7 +8136,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
2745
2827
|
let parameterTypes = signature.parameterTypes;
|
|
2746
2828
|
for (let i = 0; i < numArguments; ++i, ++index) {
|
|
2747
2829
|
let paramType = parameterTypes[i];
|
|
@@ -2750,7 +2832,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
2750
2832
|
operands[index] = paramExpr;
|
|
2751
2833
|
}
|
|
2752
2834
|
assert(index == numArgumentsInclThis);
|
|
2753
|
-
@@ -6697,
|
|
2835
|
+
@@ -6697,39 +8369,940 @@ export class Compiler extends DiagnosticEmitter {
|
|
2754
2836
|
return stub;
|
|
2755
2837
|
}
|
|
2756
2838
|
|
|
@@ -2865,9 +2947,6 @@ index f99bd5a..d9c1b77 100644
|
|
|
2865
2947
|
- let usizeType = this.options.usizeType;
|
|
2866
2948
|
- let sizeTypeRef = usizeType.toRef();
|
|
2867
2949
|
- let parameterTypes = instance.signature.parameterTypes;
|
|
2868
|
-
- let returnType = instance.signature.returnType;
|
|
2869
|
-
- let numParameters = parameterTypes.length;
|
|
2870
|
-
- let tempIndex = 1 + parameterTypes.length; // incl. `this`
|
|
2871
2950
|
+ let key = `${source.id}|${target.id}`;
|
|
2872
2951
|
+ let adapter = this.valueArityAdapters.get(key);
|
|
2873
2952
|
+ if (!adapter) {
|
|
@@ -3718,13 +3797,10 @@ index f99bd5a..d9c1b77 100644
|
|
|
3718
3797
|
+ let usizeType = this.options.usizeType;
|
|
3719
3798
|
+ let sizeTypeRef = usizeType.toRef();
|
|
3720
3799
|
+ let parameterTypes = instance.signature.parameterTypes;
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
// Switch over this's rtId and map it to the respective overload
|
|
3726
|
-
let builder = new SwitchBuilder(this.module,
|
|
3727
|
-
@@ -7011,7 +9516,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
3800
|
+
let returnType = instance.signature.returnType;
|
|
3801
|
+
let numParameters = parameterTypes.length;
|
|
3802
|
+
let tempIndex = 1 + parameterTypes.length; // incl. `this`
|
|
3803
|
+
@@ -7011,7 +9584,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
3728
3804
|
lastOperand
|
|
3729
3805
|
], lastOperandType.toRef());
|
|
3730
3806
|
this.operandsTostack(instance.signature, operands);
|
|
@@ -3733,7 +3809,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3733
3809
|
if (returnType != Type.void && immediatelyDropped) {
|
|
3734
3810
|
expr = module.drop(expr);
|
|
3735
3811
|
this.currentType = Type.void;
|
|
3736
|
-
@@ -7029,6 +
|
|
3812
|
+
@@ -7029,6 +9602,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
3737
3813
|
|
|
3738
3814
|
if (operands) this.operandsTostack(instance.signature, operands);
|
|
3739
3815
|
let expr = module.call(instance.internalName, operands, returnType.toRef());
|
|
@@ -3743,7 +3819,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3743
3819
|
this.currentType = returnType;
|
|
3744
3820
|
return expr;
|
|
3745
3821
|
}
|
|
3746
|
-
@@ -7122,10 +
|
|
3822
|
+
@@ -7122,10 +9698,19 @@ export class Compiler extends DiagnosticEmitter {
|
|
3747
3823
|
let stmts = new Array<ExpressionRef>();
|
|
3748
3824
|
let sizeTypeRef = this.options.sizeTypeRef;
|
|
3749
3825
|
|
|
@@ -3763,7 +3839,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3763
3839
|
functionArg = module.local_get(functionArgLocal.index, sizeTypeRef);
|
|
3764
3840
|
}
|
|
3765
3841
|
|
|
3766
|
-
@@ -7133,10 +
|
|
3842
|
+
@@ -7133,10 +9718,16 @@ export class Compiler extends DiagnosticEmitter {
|
|
3767
3843
|
// provided, so we must set `argumentsLength` in any case. Inject setting it
|
|
3768
3844
|
// into the index argument, which becomes executed last after any operands.
|
|
3769
3845
|
let argumentsLength = this.ensureArgumentsLength();
|
|
@@ -3784,7 +3860,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3784
3860
|
|
|
3785
3861
|
if (operands) this.operandsTostack(signature, operands);
|
|
3786
3862
|
let expr = module.call_indirect(
|
|
3787
|
-
@@ -7146,6 +
|
|
3863
|
+
@@ -7146,6 +9737,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
3788
3864
|
signature.paramRefs,
|
|
3789
3865
|
signature.resultRefs
|
|
3790
3866
|
);
|
|
@@ -3792,7 +3868,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3792
3868
|
this.currentType = returnType;
|
|
3793
3869
|
stmts.push(expr);
|
|
3794
3870
|
return module.flatten(stmts, returnType.toRef());
|
|
3795
|
-
@@ -7176,6 +
|
|
3871
|
+
@@ -7176,6 +9768,12 @@ export class Compiler extends DiagnosticEmitter {
|
|
3796
3872
|
let module = this.module;
|
|
3797
3873
|
let targetExpression = expression.expression;
|
|
3798
3874
|
let resolver = this.resolver;
|
|
@@ -3805,7 +3881,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3805
3881
|
let targetElement = resolver.lookupExpression(targetExpression, this.currentFlow, Type.auto, ReportMode.Swallow);
|
|
3806
3882
|
if (targetElement && targetElement.kind == ElementKind.Enum) {
|
|
3807
3883
|
const elementExpr = this.compileExpression(expression.elementExpression, Type.i32, Constraints.ConvImplicit);
|
|
3808
|
-
@@ -7202,9 +
|
|
3884
|
+
@@ -7202,9 +9800,11 @@ export class Compiler extends DiagnosticEmitter {
|
|
3809
3885
|
expression.range
|
|
3810
3886
|
);
|
|
3811
3887
|
}
|
|
@@ -3818,7 +3894,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3818
3894
|
}
|
|
3819
3895
|
}
|
|
3820
3896
|
this.error(
|
|
3821
|
-
@@ -7224,6 +
|
|
3897
|
+
@@ -7224,6 +9824,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
3822
3898
|
assert(!declaration.typeParameters); // function expression cannot be generic
|
|
3823
3899
|
let flow = this.currentFlow;
|
|
3824
3900
|
let sourceFunction = flow.sourceFunction;
|
|
@@ -3832,7 +3908,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3832
3908
|
let isNamed = declaration.name.text.length > 0;
|
|
3833
3909
|
let isSemanticallyAnonymous = !isNamed || contextualType != Type.void;
|
|
3834
3910
|
let prototype = new FunctionPrototype(
|
|
3835
|
-
@@ -7237,6 +
|
|
3911
|
+
@@ -7237,6 +9844,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
3836
3912
|
let instance: Function | null;
|
|
3837
3913
|
let contextualTypeArguments = cloneMap(flow.contextualTypeArguments);
|
|
3838
3914
|
let module = this.module;
|
|
@@ -3840,7 +3916,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3840
3916
|
|
|
3841
3917
|
// compile according to context. this differs from a normal function in that omitted parameter
|
|
3842
3918
|
// and return types can be inferred and omitted arguments can be replaced with dummies.
|
|
3843
|
-
@@ -7280,7 +
|
|
3919
|
+
@@ -7280,7 +9888,18 @@ export class Compiler extends DiagnosticEmitter {
|
|
3844
3920
|
|
|
3845
3921
|
// check non-omitted return type
|
|
3846
3922
|
let returnType = contextualSignature.returnType;
|
|
@@ -3860,7 +3936,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3860
3936
|
let resolvedType = this.resolver.resolveType(
|
|
3861
3937
|
signatureNode.returnType, flow,
|
|
3862
3938
|
sourceFunction.parent,
|
|
3863
|
-
@@ -7334,7 +
|
|
3939
|
+
@@ -7334,7 +9953,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
3864
3940
|
signature,
|
|
3865
3941
|
contextualTypeArguments
|
|
3866
3942
|
);
|
|
@@ -3869,7 +3945,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3869
3945
|
let worked = this.compileFunction(instance);
|
|
3870
3946
|
this.currentType = contextualSignature.type;
|
|
3871
3947
|
if (!worked) return module.unreachable();
|
|
3872
|
-
@@ -7343,7 +
|
|
3948
|
+
@@ -7343,7 +9962,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
3873
3949
|
} else {
|
|
3874
3950
|
instance = this.resolver.resolveFunction(prototype, null, contextualTypeArguments);
|
|
3875
3951
|
if (!instance) return this.module.unreachable();
|
|
@@ -3878,7 +3954,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3878
3954
|
let worked = this.compileFunction(instance);
|
|
3879
3955
|
this.currentType = instance.signature.type;
|
|
3880
3956
|
if (!worked) return module.unreachable();
|
|
3881
|
-
@@ -7354,6 +
|
|
3957
|
+
@@ -7354,6 +9973,27 @@ export class Compiler extends DiagnosticEmitter {
|
|
3882
3958
|
? module.i64(i64_low(offset), i64_high(offset))
|
|
3883
3959
|
: module.i32(i64_low(offset));
|
|
3884
3960
|
|
|
@@ -3906,7 +3982,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3906
3982
|
// add a constant local referring to the function if applicable
|
|
3907
3983
|
if (!isSemanticallyAnonymous) {
|
|
3908
3984
|
let fname = instance.name;
|
|
3909
|
-
@@ -7403,6 +
|
|
3985
|
+
@@ -7403,6 +10043,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
3910
3986
|
let flow = this.currentFlow;
|
|
3911
3987
|
let sourceFunction = flow.sourceFunction;
|
|
3912
3988
|
|
|
@@ -3916,7 +3992,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3916
3992
|
// check special keywords first
|
|
3917
3993
|
switch (expression.kind) {
|
|
3918
3994
|
case NodeKind.Null: {
|
|
3919
|
-
@@ -7439,6 +
|
|
3995
|
+
@@ -7439,6 +10082,15 @@ export class Compiler extends DiagnosticEmitter {
|
|
3920
3996
|
}
|
|
3921
3997
|
case NodeKind.This: {
|
|
3922
3998
|
let thisType = sourceFunction.signature.thisType;
|
|
@@ -3932,7 +4008,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3932
4008
|
if (!thisType) {
|
|
3933
4009
|
this.error(
|
|
3934
4010
|
DiagnosticCode._this_cannot_be_referenced_in_current_location,
|
|
3935
|
-
@@ -7466,6 +
|
|
4011
|
+
@@ -7466,6 +10118,17 @@ export class Compiler extends DiagnosticEmitter {
|
|
3936
4012
|
return module.local_get(thisLocal.index, thisType.toRef());
|
|
3937
4013
|
}
|
|
3938
4014
|
case NodeKind.Super: {
|
|
@@ -3950,7 +4026,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3950
4026
|
if (sourceFunction.is(CommonFlags.Constructor)) {
|
|
3951
4027
|
if (flow.is(FlowFlags.CtorParamContext)) {
|
|
3952
4028
|
this.error(
|
|
3953
|
-
@@ -7545,6 +
|
|
4029
|
+
@@ -7545,6 +10208,26 @@ export class Compiler extends DiagnosticEmitter {
|
|
3954
4030
|
return this.compileInlineConstant(local, contextualType, constraints);
|
|
3955
4031
|
}
|
|
3956
4032
|
let localIndex = local.index;
|
|
@@ -3977,7 +4053,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3977
4053
|
if (!flow.isLocalFlag(localIndex, LocalFlags.Initialized)) {
|
|
3978
4054
|
this.error(
|
|
3979
4055
|
DiagnosticCode.Variable_0_is_used_before_being_assigned,
|
|
3980
|
-
@@ -7559,14 +
|
|
4056
|
+
@@ -7559,14 +10242,12 @@ export class Compiler extends DiagnosticEmitter {
|
|
3981
4057
|
this.currentType = localType;
|
|
3982
4058
|
}
|
|
3983
4059
|
|
|
@@ -3998,7 +4074,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
3998
4074
|
}
|
|
3999
4075
|
let expr = module.local_get(localIndex, localType.toRef());
|
|
4000
4076
|
if (isNonNull && localType.isNullableExternalReference && this.options.hasFeature(Feature.GC)) {
|
|
4001
|
-
@@ -7582,8 +
|
|
4077
|
+
@@ -7582,8 +10263,10 @@ export class Compiler extends DiagnosticEmitter {
|
|
4002
4078
|
if (!this.compileGlobalLazy(global, expression)) {
|
|
4003
4079
|
return module.unreachable();
|
|
4004
4080
|
}
|
|
@@ -4010,7 +4086,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4010
4086
|
this.error(
|
|
4011
4087
|
DiagnosticCode.Variable_0_used_before_its_declaration,
|
|
4012
4088
|
expression.range,
|
|
4013
|
-
@@ -7603,6 +
|
|
4089
|
+
@@ -7603,6 +10286,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
4014
4090
|
if (global.is(CommonFlags.DefinitelyAssigned) && globalType.isReference && !globalType.isNullableReference) {
|
|
4015
4091
|
expr = this.makeRuntimeNonNullCheck(expr, globalType, expression);
|
|
4016
4092
|
}
|
|
@@ -4018,7 +4094,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4018
4094
|
this.currentType = globalType;
|
|
4019
4095
|
return expr;
|
|
4020
4096
|
}
|
|
4021
|
-
@@ -7656,6 +
|
|
4097
|
+
@@ -7656,6 +10340,23 @@ export class Compiler extends DiagnosticEmitter {
|
|
4022
4098
|
this.currentType = Type.func;
|
|
4023
4099
|
return module.ref_func(functionInstance.internalName, ensureType(functionInstance.type));
|
|
4024
4100
|
}
|
|
@@ -4042,7 +4118,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4042
4118
|
let offset = this.ensureRuntimeFunction(functionInstance);
|
|
4043
4119
|
this.currentType = functionInstance.signature.type;
|
|
4044
4120
|
return this.options.isWasm64
|
|
4045
|
-
@@ -8070,6 +
|
|
4121
|
+
@@ -8070,6 +10771,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
4046
4122
|
switch (expression.literalKind) {
|
|
4047
4123
|
case LiteralKind.Array: {
|
|
4048
4124
|
assert(!implicitlyNegate);
|
|
@@ -4052,7 +4128,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4052
4128
|
return this.compileArrayLiteral(
|
|
4053
4129
|
<ArrayLiteralExpression>expression,
|
|
4054
4130
|
contextualType,
|
|
4055
|
-
@@ -8122,14 +
|
|
4131
|
+
@@ -8122,14 +10826,15 @@ export class Compiler extends DiagnosticEmitter {
|
|
4056
4132
|
assert(!implicitlyNegate);
|
|
4057
4133
|
return this.compileObjectLiteral(<ObjectLiteralExpression>expression, contextualType);
|
|
4058
4134
|
}
|
|
@@ -4075,7 +4151,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4075
4151
|
}
|
|
4076
4152
|
}
|
|
4077
4153
|
assert(false);
|
|
4078
|
-
@@ -8361,6 +
|
|
4154
|
+
@@ -8361,6 +11066,22 @@ export class Compiler extends DiagnosticEmitter {
|
|
4079
4155
|
return this.compileStaticArrayLiteral(expression, contextualType, constraints);
|
|
4080
4156
|
}
|
|
4081
4157
|
|
|
@@ -4098,7 +4174,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4098
4174
|
// handle normal arrays
|
|
4099
4175
|
let element = this.resolver.lookupExpression(expression, flow, this.currentType);
|
|
4100
4176
|
if (!element) return module.unreachable();
|
|
4101
|
-
@@ -8618,6 +
|
|
4177
|
+
@@ -8618,6 +11339,27 @@ export class Compiler extends DiagnosticEmitter {
|
|
4102
4178
|
|
|
4103
4179
|
// Check that contextual type is a class (TODO: hidden class for interfaces?)
|
|
4104
4180
|
let classReference = contextualType.getClass();
|
|
@@ -4126,7 +4202,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4126
4202
|
if (!classReference) {
|
|
4127
4203
|
this.error(
|
|
4128
4204
|
DiagnosticCode.Type_0_is_not_assignable_to_type_1,
|
|
4129
|
-
@@ -8625,9 +
|
|
4205
|
+
@@ -8625,9 +11367,18 @@ export class Compiler extends DiagnosticEmitter {
|
|
4130
4206
|
);
|
|
4131
4207
|
return module.unreachable();
|
|
4132
4208
|
}
|
|
@@ -4145,7 +4221,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4145
4221
|
this.error(
|
|
4146
4222
|
DiagnosticCode.Not_implemented_0,
|
|
4147
4223
|
expression.range, "Interface hidden classes"
|
|
4148
|
-
@@ -8689,6 +
|
|
4224
|
+
@@ -8689,6 +11440,11 @@ export class Compiler extends DiagnosticEmitter {
|
|
4149
4225
|
let deferredProperties = new Array<Property>();
|
|
4150
4226
|
for (let i = 0; i < numNames; ++i) {
|
|
4151
4227
|
let memberName = names[i].text;
|
|
@@ -4157,7 +4233,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4157
4233
|
let member = classReference.getMember(memberName);
|
|
4158
4234
|
if (!member || member.kind != ElementKind.PropertyPrototype) {
|
|
4159
4235
|
this.error(
|
|
4160
|
-
@@ -8736,9 +
|
|
4236
|
+
@@ -8736,9 +11492,55 @@ export class Compiler extends DiagnosticEmitter {
|
|
4161
4237
|
}
|
|
4162
4238
|
|
|
4163
4239
|
let propertyType = propertyInstance.type;
|
|
@@ -4214,7 +4290,18 @@ index f99bd5a..d9c1b77 100644
|
|
|
4214
4290
|
], setterInstance.identifierNode, true);
|
|
4215
4291
|
if (this.currentType != Type.void) { // in case
|
|
4216
4292
|
expr = module.drop(expr);
|
|
4217
|
-
@@ -
|
|
4293
|
+
@@ -8924,7 +11726,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
4294
|
+
let contextualTypeArguments = cloneMap(classInstance.contextualTypeArguments);
|
|
4295
|
+
if (baseClass) {
|
|
4296
|
+
let baseCtor = this.ensureConstructor(baseClass, reportNode);
|
|
4297
|
+
- this.checkFieldInitialization(baseClass, reportNode);
|
|
4298
|
+
+ // amxts: a class that implements an interface of fields declares them
|
|
4299
|
+
+ // again, as TypeScript has it, and they are checked as its own
|
|
4300
|
+
+ if (shapeBaseOf(classInstance) != baseClass) this.checkFieldInitialization(baseClass, reportNode);
|
|
4301
|
+
instance = new Function(
|
|
4302
|
+
CommonNames.constructor,
|
|
4303
|
+
new FunctionPrototype(
|
|
4304
|
+
@@ -9128,6 +11932,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
4218
4305
|
let resolver = this.resolver;
|
|
4219
4306
|
let target = resolver.lookupExpression(expression, flow, ctxType); // reports
|
|
4220
4307
|
if (!target) return module.unreachable();
|
|
@@ -4224,7 +4311,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4224
4311
|
let thisExpression = resolver.currentThisExpression;
|
|
4225
4312
|
if (target.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(expression);
|
|
4226
4313
|
|
|
4227
|
-
@@ -9209,7 +
|
|
4314
|
+
@@ -9209,7 +12016,12 @@ export class Compiler extends DiagnosticEmitter {
|
|
4228
4315
|
Constraints.ConvImplicit | Constraints.IsThis
|
|
4229
4316
|
);
|
|
4230
4317
|
}
|
|
@@ -4238,7 +4325,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4238
4325
|
}
|
|
4239
4326
|
case ElementKind.FunctionPrototype: {
|
|
4240
4327
|
let functionPrototype = <FunctionPrototype>target;
|
|
4241
|
-
@@ -9236,6 +
|
|
4328
|
+
@@ -9236,6 +12048,18 @@ export class Compiler extends DiagnosticEmitter {
|
|
4242
4329
|
return module.unreachable();
|
|
4243
4330
|
}
|
|
4244
4331
|
|
|
@@ -4257,7 +4344,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4257
4344
|
let offset = this.ensureRuntimeFunction(functionInstance);
|
|
4258
4345
|
return this.options.isWasm64
|
|
4259
4346
|
? module.i64(i64_low(offset), i64_high(offset))
|
|
4260
|
-
@@ -9258,6 +
|
|
4347
|
+
@@ -9258,6 +12082,11 @@ export class Compiler extends DiagnosticEmitter {
|
|
4261
4348
|
let ifThen = expression.ifThen;
|
|
4262
4349
|
let ifElse = expression.ifElse;
|
|
4263
4350
|
|
|
@@ -4269,7 +4356,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4269
4356
|
let condExpr = this.compileExpression(expression.condition, Type.bool);
|
|
4270
4357
|
let condExprTrueish = this.makeIsTrueish(condExpr, this.currentType, expression.condition);
|
|
4271
4358
|
// Try to eliminate unnecesssary branches if the condition is constant
|
|
4272
|
-
@@ -9272,
|
|
4359
|
+
@@ -9272,14 +12101,17 @@ export class Compiler extends DiagnosticEmitter {
|
|
4273
4360
|
|
|
4274
4361
|
let outerFlow = this.currentFlow;
|
|
4275
4362
|
let ifThenFlow = outerFlow.forkThen(condExpr);
|
|
@@ -4283,7 +4370,34 @@ index f99bd5a..d9c1b77 100644
|
|
|
4283
4370
|
this.currentFlow = ifElseFlow;
|
|
4284
4371
|
let ifElseExpr = this.compileExpression(ifElse, contextualType == Type.auto ? ifThenType : contextualType);
|
|
4285
4372
|
let ifElseType = this.currentType;
|
|
4286
|
-
|
|
4373
|
+
+ let lenient = false;
|
|
4374
|
+
|
|
4375
|
+
if (contextualType == Type.void) { // values, including type mismatch, are irrelevant
|
|
4376
|
+
if (ifThenType != Type.void) {
|
|
4377
|
+
@@ -9301,6 +12133,11 @@ export class Compiler extends DiagnosticEmitter {
|
|
4378
|
+
this.currentType = contextualType;
|
|
4379
|
+
return module.unreachable();
|
|
4380
|
+
}
|
|
4381
|
+
+ // amxts: `map.has(key) ? map.get(key) : fallback` - null only from a
|
|
4382
|
+
+ // lenient read is checked where it is used, as for the read alone
|
|
4383
|
+
+ lenient = commonType.isNullableReference &&
|
|
4384
|
+
+ (!ifThenType.isNullableReference || this.isLenientRead(ifThenExpr)) &&
|
|
4385
|
+
+ (!ifElseType.isNullableReference || this.isLenientRead(ifElseExpr));
|
|
4386
|
+
ifThenExpr = this.convertExpression(ifThenExpr, ifThenType, commonType, false, ifThen);
|
|
4387
|
+
ifThenType = commonType;
|
|
4388
|
+
ifElseExpr = this.convertExpression(ifElseExpr, ifElseType, commonType, false, ifElse);
|
|
4389
|
+
@@ -9311,7 +12148,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
4390
|
+
outerFlow.inheritAlternatives(ifThenFlow, ifElseFlow);
|
|
4391
|
+
this.currentFlow = outerFlow;
|
|
4392
|
+
|
|
4393
|
+
- return module.if(condExprTrueish, ifThenExpr, ifElseExpr);
|
|
4394
|
+
+ let expr = module.if(condExprTrueish, ifThenExpr, ifElseExpr);
|
|
4395
|
+
+ if (lenient) this.recordReads.add(expr);
|
|
4396
|
+
+ return expr;
|
|
4397
|
+
}
|
|
4398
|
+
|
|
4399
|
+
private compileUnaryPostfixExpression(
|
|
4400
|
+
@@ -9828,7 +12667,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
4287
4401
|
contextualType == Type.void
|
|
4288
4402
|
? Type.i32
|
|
4289
4403
|
: contextualType.isFloatValue
|
|
@@ -4292,7 +4406,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4292
4406
|
: contextualType,
|
|
4293
4407
|
Constraints.None
|
|
4294
4408
|
);
|
|
4295
|
-
@@ -9847,7 +
|
|
4409
|
+
@@ -9847,7 +12686,12 @@ export class Compiler extends DiagnosticEmitter {
|
|
4296
4410
|
return module.unreachable();
|
|
4297
4411
|
}
|
|
4298
4412
|
|
|
@@ -4306,7 +4420,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4306
4420
|
|
|
4307
4421
|
switch (this.currentType.kind) {
|
|
4308
4422
|
case TypeKind.Bool:
|
|
4309
|
-
@@ -9887,10 +
|
|
4423
|
+
@@ -9887,10 +12731,13 @@ export class Compiler extends DiagnosticEmitter {
|
|
4310
4424
|
case Token.TypeOf: {
|
|
4311
4425
|
return this.compileTypeof(expression, contextualType, constraints);
|
|
4312
4426
|
}
|
|
@@ -4321,7 +4435,16 @@ index f99bd5a..d9c1b77 100644
|
|
|
4321
4435
|
);
|
|
4322
4436
|
return module.unreachable();
|
|
4323
4437
|
}
|
|
4324
|
-
@@ -
|
|
4438
|
+
@@ -10067,6 +12914,8 @@ export class Compiler extends DiagnosticEmitter {
|
|
4439
|
+
addDebugLocation(expr: ExpressionRef, range: Range): void {
|
|
4440
|
+
let targetFunction = this.currentFlow.targetFunction;
|
|
4441
|
+
let source = range.source;
|
|
4442
|
+
+ // amxts: what the compiler makes itself has no file to point at
|
|
4443
|
+
+ if (source == Source.native) return;
|
|
4444
|
+
if (source.debugInfoIndex < 0) source.debugInfoIndex = this.module.addDebugInfoFile(source.normalizedPath);
|
|
4445
|
+
// It's possible that an `expr` is seen multiple times, for example when
|
|
4446
|
+
// first adding debug information for an inner expression and later on for
|
|
4447
|
+
@@ -10220,6 +13069,31 @@ export class Compiler extends DiagnosticEmitter {
|
|
4325
4448
|
case TypeKind.U64: return module.binary(BinaryOp.NeI64, expr, module.i64(0));
|
|
4326
4449
|
case TypeKind.Isize:
|
|
4327
4450
|
case TypeKind.Usize: {
|
|
@@ -4353,7 +4476,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4353
4476
|
return type.size == 64
|
|
4354
4477
|
? module.binary(BinaryOp.NeI64, expr, module.i64(0))
|
|
4355
4478
|
: expr;
|
|
4356
|
-
@@ -10323,10 +
|
|
4479
|
+
@@ -10323,10 +13197,59 @@ export class Compiler extends DiagnosticEmitter {
|
|
4357
4480
|
}
|
|
4358
4481
|
}
|
|
4359
4482
|
|
|
@@ -4413,7 +4536,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4413
4536
|
if (type == stringType) {
|
|
4414
4537
|
return expr;
|
|
4415
4538
|
}
|
|
4416
|
-
@@ -10364,7 +
|
|
4539
|
+
@@ -10364,7 +13287,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
4417
4540
|
type.nonNullableType,
|
|
4418
4541
|
reportNode
|
|
4419
4542
|
),
|
|
@@ -4422,7 +4545,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
4422
4545
|
);
|
|
4423
4546
|
}
|
|
4424
4547
|
let toStringReturnType = toStringSignature.returnType;
|
|
4425
|
-
@@ -10436,85 +
|
|
4548
|
+
@@ -10436,85 +13359,664 @@ export class Compiler extends DiagnosticEmitter {
|
|
4426
4549
|
);
|
|
4427
4550
|
}
|
|
4428
4551
|
|
|
@@ -5159,21 +5282,32 @@ index f99bd5a..d9c1b77 100644
|
|
|
5159
5282
|
}
|
|
5160
5283
|
|
|
5161
5284
|
/** Makes a call to `abort`, if present, otherwise creates a trap. */
|
|
5162
|
-
@@ -
|
|
5285
|
+
@@ -10554,20 +14056,72 @@ export class Compiler extends DiagnosticEmitter {
|
|
5286
|
+
let filenameExpr = this.ensureStaticString(codeLocation.range.source.normalizedPath);
|
|
5163
5287
|
let range = codeLocation.range;
|
|
5164
5288
|
let source = range.source;
|
|
5289
|
+
+ let abortCall = module.call(
|
|
5290
|
+
+ abortInstance.internalName, [
|
|
5291
|
+
+ messageExpr,
|
|
5292
|
+
+ filenameExpr,
|
|
5293
|
+
+ module.i32(source.lineAt(range.start)),
|
|
5294
|
+
+ module.i32(source.columnAt())
|
|
5295
|
+
+ ],
|
|
5296
|
+
+ TypeRef.None
|
|
5297
|
+
+ );
|
|
5298
|
+
+ // amxts: a failed call's stack stops at this call - its place, in the source map
|
|
5299
|
+
+ if (this.options.sourceMap) this.addDebugLocation(abortCall, range);
|
|
5165
5300
|
return module.block(null, [
|
|
5166
5301
|
- module.call(
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
TypeRef.None
|
|
5302
|
+
- abortInstance.internalName, [
|
|
5303
|
+
- messageExpr,
|
|
5304
|
+
- filenameExpr,
|
|
5305
|
+
- module.i32(source.lineAt(range.start)),
|
|
5306
|
+
- module.i32(source.columnAt())
|
|
5307
|
+
- ],
|
|
5308
|
+
- TypeRef.None
|
|
5175
5309
|
- ),
|
|
5176
|
-
+ )
|
|
5310
|
+
+ this.makeAbortReset(abortCall),
|
|
5177
5311
|
module.unreachable()
|
|
5178
5312
|
]);
|
|
5179
5313
|
}
|
|
@@ -5188,7 +5322,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
5188
5322
|
+ let module = this.module;
|
|
5189
5323
|
+ let target = this.currentFlow.targetFunction;
|
|
5190
5324
|
+ let throwHood = this.unwindsIn(target) ? this.exceptionFunction("__throw", reportNode) : null;
|
|
5191
|
-
+ if (!throwHood) return this.makeStaticAbort(this.ensureStaticString(message), reportNode);
|
|
5325
|
+
+ if (!throwHood) return this.makeStaticAbort(this.ensureStaticString(`${kind}: ${message}`), reportNode);
|
|
5192
5326
|
+ let range = reportNode.range;
|
|
5193
5327
|
+ let source = range.source;
|
|
5194
5328
|
+ let previousType = this.currentType;
|
|
@@ -5203,6 +5337,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
5203
5337
|
+ module.i32(source.lineAt(range.start)),
|
|
5204
5338
|
+ module.i32(source.columnAt())
|
|
5205
5339
|
+ ], TypeRef.I32);
|
|
5340
|
+
+ if (this.options.sourceMap) this.addDebugLocation(thrown, range);
|
|
5206
5341
|
+ return module.block(null, [ module.if(thrown, this.makeUnwind()), module.unreachable() ]);
|
|
5207
5342
|
+ }
|
|
5208
5343
|
+
|
|
@@ -5229,7 +5364,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
5229
5364
|
/** Makes a runtime non-null check, e.g. on `<Type>possiblyNull` or `possiblyNull!`. */
|
|
5230
5365
|
makeRuntimeNonNullCheck(
|
|
5231
5366
|
/** Expression being checked. */
|
|
5232
|
-
@@ -10575,7 +
|
|
5367
|
+
@@ -10575,7 +14129,9 @@ export class Compiler extends DiagnosticEmitter {
|
|
5233
5368
|
/** Type of the expression. */
|
|
5234
5369
|
type: Type,
|
|
5235
5370
|
/** Report node. */
|
|
@@ -5240,7 +5375,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
5240
5375
|
): ExpressionRef {
|
|
5241
5376
|
let module = this.module;
|
|
5242
5377
|
let flow = this.currentFlow;
|
|
5243
|
-
@@ -10584,10 +
|
|
5378
|
+
@@ -10584,10 +14140,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
5244
5379
|
if (!flow.canOverflow(expr, type)) flow.setLocalFlag(tempIndex, LocalFlags.Wrapped);
|
|
5245
5380
|
flow.setLocalFlag(tempIndex, LocalFlags.NonNull);
|
|
5246
5381
|
|
|
@@ -5252,7 +5387,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
5252
5387
|
|
|
5253
5388
|
if (type.isExternalReference) {
|
|
5254
5389
|
let nonNullExpr = module.local_get(tempIndex, type.toRef());
|
|
5255
|
-
@@ -10629,10 +
|
|
5390
|
+
@@ -10629,10 +14182,7 @@ export class Compiler extends DiagnosticEmitter {
|
|
5256
5391
|
let temp = flow.getTempLocal(type);
|
|
5257
5392
|
let tempIndex = temp.index;
|
|
5258
5393
|
|
|
@@ -5264,7 +5399,7 @@ index f99bd5a..d9c1b77 100644
|
|
|
5264
5399
|
|
|
5265
5400
|
if (!toType.isNullableReference || flow.isNonnull(expr, type)) {
|
|
5266
5401
|
// Simplify if the value cannot be `null`. If toType is non-nullable, a
|
|
5267
|
-
@@ -10725,3 +
|
|
5402
|
+
@@ -10725,3 +14275,505 @@ function mangleImportName(
|
|
5268
5403
|
);
|
|
5269
5404
|
}
|
|
5270
5405
|
}
|
|
@@ -5802,10 +5937,18 @@ index 016ba4e..3fda5d4 100644
|
|
|
5802
5937
|
"Cannot create an instance of an abstract class.": 2511,
|
|
5803
5938
|
"Non-abstract class '{0}' does not implement inherited abstract member '{1}' from '{2}'.": 2515,
|
|
5804
5939
|
diff --git a/src/flow.ts b/src/flow.ts
|
|
5805
|
-
index ddc7941..
|
|
5940
|
+
index ddc7941..fbe7b3b 100644
|
|
5806
5941
|
--- a/src/flow.ts
|
|
5807
5942
|
+++ b/src/flow.ts
|
|
5808
|
-
@@ -
|
|
5943
|
+
@@ -46,6 +46,7 @@ import {
|
|
5944
|
+
getLocalGetIndex,
|
|
5945
|
+
isLocalTee,
|
|
5946
|
+
getLocalSetValue,
|
|
5947
|
+
+ getGlobalSetValue,
|
|
5948
|
+
getGlobalGetName,
|
|
5949
|
+
getBinaryOp,
|
|
5950
|
+
getBinaryLeft,
|
|
5951
|
+
@@ -71,12 +72,15 @@ import {
|
|
5809
5952
|
getUnaryValue,
|
|
5810
5953
|
getCallOperandAt,
|
|
5811
5954
|
getCallOperandCount,
|
|
@@ -5822,7 +5965,7 @@ index ddc7941..b0f883a 100644
|
|
|
5822
5965
|
} from "./common";
|
|
5823
5966
|
|
|
5824
5967
|
import {
|
|
5825
|
-
@@ -88,7 +
|
|
5968
|
+
@@ -88,7 +92,8 @@ import {
|
|
5826
5969
|
} from "./diagnostics";
|
|
5827
5970
|
|
|
5828
5971
|
import {
|
|
@@ -5832,7 +5975,7 @@ index ddc7941..b0f883a 100644
|
|
|
5832
5975
|
} from "./ast";
|
|
5833
5976
|
|
|
5834
5977
|
import {
|
|
5835
|
-
@@ -259,6 +
|
|
5978
|
+
@@ -259,6 +264,14 @@ export class Flow {
|
|
5836
5979
|
localFlags: LocalFlags[] = [];
|
|
5837
5980
|
/** Field flags on `this`. Constructors only. */
|
|
5838
5981
|
thisFieldFlags: Map<Property,FieldFlags> | null = null;
|
|
@@ -5847,7 +5990,7 @@ index ddc7941..b0f883a 100644
|
|
|
5847
5990
|
/** The label we break to when encountering a return statement, when inlining. */
|
|
5848
5991
|
inlineReturnLabel: string | null = null;
|
|
5849
5992
|
/** Alternative flows if a compound expression is true-ish. */
|
|
5850
|
-
@@ -354,6 +
|
|
5993
|
+
@@ -354,6 +367,8 @@ export class Flow {
|
|
5851
5994
|
branch.continueLabel = this.continueLabel;
|
|
5852
5995
|
}
|
|
5853
5996
|
branch.localFlags = this.localFlags.slice();
|
|
@@ -5856,7 +5999,7 @@ index ddc7941..b0f883a 100644
|
|
|
5856
5999
|
if (this.sourceFunction.is(CommonFlags.Constructor)) {
|
|
5857
6000
|
let thisFieldFlags = assert(this.thisFieldFlags);
|
|
5858
6001
|
branch.thisFieldFlags = cloneMap(thisFieldFlags);
|
|
5859
|
-
@@ -540,9 +
|
|
6002
|
+
@@ -540,9 +555,33 @@ export class Flow {
|
|
5860
6003
|
lookup(name: string): Element | null {
|
|
5861
6004
|
let element = this.lookupLocal(name);
|
|
5862
6005
|
if (element) return element;
|
|
@@ -5890,7 +6033,7 @@ index ddc7941..b0f883a 100644
|
|
|
5890
6033
|
/** Tests if the local at the specified index has the specified flag or flags. */
|
|
5891
6034
|
isLocalFlag(index: i32, flag: LocalFlags, defaultIfInlined: bool = true): bool {
|
|
5892
6035
|
if (index < 0) return defaultIfInlined;
|
|
5893
|
-
@@ -667,6 +
|
|
6036
|
+
@@ -667,6 +706,7 @@ export class Flow {
|
|
5894
6037
|
this.flags = this.flags | otherFlags; // what happens before is still true
|
|
5895
6038
|
this.localFlags = other.localFlags;
|
|
5896
6039
|
this.thisFieldFlags = other.thisFieldFlags;
|
|
@@ -5898,7 +6041,7 @@ index ddc7941..b0f883a 100644
|
|
|
5898
6041
|
}
|
|
5899
6042
|
|
|
5900
6043
|
|
|
5901
|
-
@@ -768,6 +
|
|
6044
|
+
@@ -768,6 +808,9 @@ export class Flow {
|
|
5902
6045
|
|
|
5903
6046
|
// field flags do not matter here since there's only INITIALIZED, which can
|
|
5904
6047
|
// only be set if it has been observed prior to entering the branch.
|
|
@@ -5908,7 +6051,7 @@ index ddc7941..b0f883a 100644
|
|
|
5908
6051
|
}
|
|
5909
6052
|
|
|
5910
6053
|
/** Inherits two alternate branches to become this flow, i.e. then with else. */
|
|
5911
|
-
@@ -893,6 +
|
|
6054
|
+
@@ -893,6 +936,15 @@ export class Flow {
|
|
5912
6055
|
}
|
|
5913
6056
|
}
|
|
5914
6057
|
|
|
@@ -5924,7 +6067,7 @@ index ddc7941..b0f883a 100644
|
|
|
5924
6067
|
// field flags (currently only INITIALIZED, so can simplify)
|
|
5925
6068
|
let leftFieldFlags = left.thisFieldFlags;
|
|
5926
6069
|
if (leftFieldFlags) {
|
|
5927
|
-
@@ -944,6 +
|
|
6070
|
+
@@ -944,6 +996,18 @@ export class Flow {
|
|
5928
6071
|
}
|
|
5929
6072
|
}
|
|
5930
6073
|
}
|
|
@@ -5943,7 +6086,7 @@ index ddc7941..b0f883a 100644
|
|
|
5943
6086
|
if (needsRecompile) {
|
|
5944
6087
|
// Reset function locals to state before the compilation attempt
|
|
5945
6088
|
assert(localsByIndex.length >= numLocalsBefore);
|
|
5946
|
-
@@ -971,10 +
|
|
6089
|
+
@@ -971,10 +1035,91 @@ export class Flow {
|
|
5947
6090
|
let local = this.targetFunction.localsByIndex[getLocalGetIndex(expr)];
|
|
5948
6091
|
return !local.type.isNullableReference || this.isLocalFlag(local.index, LocalFlags.NonNull, false);
|
|
5949
6092
|
}
|
|
@@ -6000,6 +6143,13 @@ index ddc7941..b0f883a 100644
|
|
|
6000
6143
|
+ * amxts: forgets the paths rooted at local `index` (it was assigned), or,
|
|
6001
6144
|
+ * with `getter`, those that go through that field (it was assigned).
|
|
6002
6145
|
+ */
|
|
6146
|
+
+ /** amxts: remembers that global `name` is not null here - it was assigned an object. */
|
|
6147
|
+
+ setGlobalNonNull(name: string): void {
|
|
6148
|
+
+ let paths = this.nonNullPaths;
|
|
6149
|
+
+ if (!paths) this.nonNullPaths = paths = new Set();
|
|
6150
|
+
+ paths.add("g@" + name);
|
|
6151
|
+
+ }
|
|
6152
|
+
+
|
|
6003
6153
|
+ /** amxts: forgets the paths rooted at global `name` - it was assigned. */
|
|
6004
6154
|
+ forgetGlobalPaths(name: string): void {
|
|
6005
6155
|
+ let paths = this.nonNullPaths;
|
|
@@ -6028,7 +6178,20 @@ index ddc7941..b0f883a 100644
|
|
|
6028
6178
|
/** Updates local states to reflect that this branch is only taken when `expr` is true-ish. */
|
|
6029
6179
|
private inheritNonnullIfTrue(
|
|
6030
6180
|
/** Expression being true. */
|
|
6031
|
-
@@ -
|
|
6181
|
+
@@ -984,6 +1129,12 @@ export class Flow {
|
|
6182
|
+
): void {
|
|
6183
|
+
// A: `expr` is true-ish -> Q: how did that happen?
|
|
6184
|
+
|
|
6185
|
+
+ // amxts: a call checked for an error is the call - see checkedCallValue
|
|
6186
|
+
+ if (getExpressionId(expr) == ExpressionId.Block) {
|
|
6187
|
+
+ let value = checkedCallValue(expr);
|
|
6188
|
+
+ if (value) expr = value;
|
|
6189
|
+
+ }
|
|
6190
|
+
+
|
|
6191
|
+
// The iff argument is useful in situations like
|
|
6192
|
+
//
|
|
6193
|
+
// if (!ref) {
|
|
6194
|
+
@@ -1019,6 +1170,11 @@ export class Flow {
|
|
6032
6195
|
}
|
|
6033
6196
|
break;
|
|
6034
6197
|
}
|
|
@@ -6040,7 +6203,7 @@ index ddc7941..b0f883a 100644
|
|
|
6040
6203
|
case ExpressionId.Unary: {
|
|
6041
6204
|
switch (getUnaryOp(expr)) {
|
|
6042
6205
|
case UnaryOp.EqzI32:
|
|
6043
|
-
@@ -1056,7 +
|
|
6206
|
+
@@ -1056,7 +1212,13 @@ export class Flow {
|
|
6044
6207
|
}
|
|
6045
6208
|
break;
|
|
6046
6209
|
}
|
|
@@ -6054,7 +6217,19 @@ index ddc7941..b0f883a 100644
|
|
|
6054
6217
|
// handle string eq/ne/not overloads
|
|
6055
6218
|
let name = getCallTarget(expr);
|
|
6056
6219
|
if (name == BuiltinNames.String_eq) {
|
|
6057
|
-
@@ -
|
|
6220
|
+
@@ -1097,6 +1259,11 @@ export class Flow {
|
|
6221
|
+
iff: Flow | null = null
|
|
6222
|
+
): void {
|
|
6223
|
+
// A: `expr` is false-ish -> Q: how did that happen?
|
|
6224
|
+
+ // amxts: a call checked for an error is the call - see checkedCallValue
|
|
6225
|
+
+ if (getExpressionId(expr) == ExpressionId.Block) {
|
|
6226
|
+
+ let value = checkedCallValue(expr);
|
|
6227
|
+
+ if (value) expr = value;
|
|
6228
|
+
+ }
|
|
6229
|
+
switch (getExpressionId(expr)) {
|
|
6230
|
+
case ExpressionId.Unary: {
|
|
6231
|
+
switch (getUnaryOp(expr)) {
|
|
6232
|
+
@@ -1211,7 +1378,11 @@ export class Flow {
|
|
6058
6233
|
// overflows if the conversion does (globals are wrapped on set)
|
|
6059
6234
|
case ExpressionId.GlobalGet: {
|
|
6060
6235
|
// TODO: this is inefficient because it has to read a string
|
|
@@ -6067,7 +6242,7 @@ index ddc7941..b0f883a 100644
|
|
|
6067
6242
|
assert(global.kind == ElementKind.Global || global.kind == ElementKind.EnumValue);
|
|
6068
6243
|
return canConversionOverflow((<TypedElement>global).type, type);
|
|
6069
6244
|
}
|
|
6070
|
-
@@ -1477,3 +
|
|
6245
|
+
@@ -1477,3 +1648,62 @@ function canConversionOverflow(fromType: Type, toType: Type): bool {
|
|
6071
6246
|
fromType.isSignedIntegerValue != toType.isSignedIntegerValue // signedness mismatch
|
|
6072
6247
|
);
|
|
6073
6248
|
}
|
|
@@ -6091,10 +6266,30 @@ index ddc7941..b0f883a 100644
|
|
|
6091
6266
|
+ let inner = fieldPathKey(getCallOperandAt(expr, 0));
|
|
6092
6267
|
+ return inner != null ? inner + ">" + name : null;
|
|
6093
6268
|
+ }
|
|
6269
|
+
+ case ExpressionId.Block: {
|
|
6270
|
+
+ let value = checkedCallValue(expr);
|
|
6271
|
+
+ return value ? fieldPathKey(value) : null;
|
|
6272
|
+
+ }
|
|
6094
6273
|
+ }
|
|
6095
6274
|
+ return null;
|
|
6096
6275
|
+}
|
|
6097
6276
|
+
|
|
6277
|
+
+/**
|
|
6278
|
+
+ * amxts: in a program with a try, a call is checked for an error it threw -
|
|
6279
|
+
+ * (set temp (call)) (if __thrown unwind) (get temp), Compiler.makeUnwindCheck
|
|
6280
|
+
+ * - and what it reads is still the call's. The call, or 0 for any other block.
|
|
6281
|
+
+ */
|
|
6282
|
+
+export function checkedCallValue(expr: ExpressionRef): ExpressionRef {
|
|
6283
|
+
+ if (getBlockName(expr) != null || getBlockChildCount(expr) != 3) return 0;
|
|
6284
|
+
+ if (getExpressionId(getBlockChildAt(expr, 1)) != ExpressionId.If) return 0;
|
|
6285
|
+
+ let set = getBlockChildAt(expr, 0);
|
|
6286
|
+
+ switch (getExpressionId(set)) {
|
|
6287
|
+
+ case ExpressionId.LocalSet: return getLocalSetValue(set);
|
|
6288
|
+
+ case ExpressionId.GlobalSet: return getGlobalSetValue(set);
|
|
6289
|
+
+ }
|
|
6290
|
+
+ return 0;
|
|
6291
|
+
+}
|
|
6292
|
+
+
|
|
6098
6293
|
+function copyPaths(paths: Set<string>): Set<string> {
|
|
6099
6294
|
+ let copy = new Set<string>();
|
|
6100
6295
|
+ for (let _values = Set_values(paths), i = 0, k = _values.length; i < k; ++i) copy.add(_values[i]);
|
|
@@ -6110,8 +6305,24 @@ index ddc7941..b0f883a 100644
|
|
|
6110
6305
|
+ }
|
|
6111
6306
|
+ return both;
|
|
6112
6307
|
+}
|
|
6308
|
+
diff --git a/src/module.ts b/src/module.ts
|
|
6309
|
+
index def4e78..f9cabf9 100644
|
|
6310
|
+
--- a/src/module.ts
|
|
6311
|
+
+++ b/src/module.ts
|
|
6312
|
+
@@ -3276,6 +3276,11 @@ export function getLocalSetValue(expr: ExpressionRef): ExpressionRef {
|
|
6313
|
+
return binaryen._BinaryenLocalSetGetValue(expr);
|
|
6314
|
+
}
|
|
6315
|
+
|
|
6316
|
+
+// amxts: the value a global.set stores - see Flow's fieldPathKey
|
|
6317
|
+
+export function getGlobalSetValue(expr: ExpressionRef): ExpressionRef {
|
|
6318
|
+
+ return binaryen._BinaryenGlobalSetGetValue(expr);
|
|
6319
|
+
+}
|
|
6320
|
+
+
|
|
6321
|
+
export function isLocalTee(expr: ExpressionRef): bool {
|
|
6322
|
+
return binaryen._BinaryenLocalSetIsTee(expr);
|
|
6323
|
+
}
|
|
6113
6324
|
diff --git a/src/parser.ts b/src/parser.ts
|
|
6114
|
-
index 157351c..
|
|
6325
|
+
index 157351c..11c0184 100644
|
|
6115
6326
|
--- a/src/parser.ts
|
|
6116
6327
|
+++ b/src/parser.ts
|
|
6117
6328
|
@@ -31,7 +31,8 @@ import {
|
|
@@ -6767,7 +6978,7 @@ index 157351c..10c3f5c 100644
|
|
|
6767
6978
|
} else {
|
|
6768
6979
|
if (!suppressErrors) {
|
|
6769
6980
|
this.error(
|
|
6770
|
-
@@ -678,11 +1212,
|
|
6981
|
+
@@ -678,11 +1212,145 @@ export class Parser extends DiagnosticEmitter {
|
|
6771
6982
|
return null;
|
|
6772
6983
|
}
|
|
6773
6984
|
// ... | type
|
|
@@ -6822,6 +7033,21 @@ index 157351c..10c3f5c 100644
|
|
|
6822
7033
|
+ continue;
|
|
6823
7034
|
+ }
|
|
6824
7035
|
+
|
|
7036
|
+
+ // amxts: `boolean | ((player: Player) => boolean)` - a yes or no that is
|
|
7037
|
+
+ // fixed, or that depends on who asks. Held as the function, as text is:
|
|
7038
|
+
+ // a boolean given where this type is declared becomes a function
|
|
7039
|
+
+ // returning it (Compiler.compileText, __boolFunction).
|
|
7040
|
+
+ let typeIsBoolean = type.kind == NodeKind.NamedType && isBoolName((<NamedTypeNode>type).name.identifier.text);
|
|
7041
|
+
+ let nextIsBoolean = nextType.kind == NodeKind.NamedType && isBoolName((<NamedTypeNode>nextType).name.identifier.text);
|
|
7042
|
+
+ if ((typeIsBoolean && nextIsFunction) || (typeIsFunction && nextIsBoolean)) {
|
|
7043
|
+
+ let fn = <FunctionTypeNode>(typeIsFunction ? type : nextType);
|
|
7044
|
+
+ fn.acceptsText = true;
|
|
7045
|
+
+ fn.range = tn.range(startPos, tn.pos);
|
|
7046
|
+
+ type = fn;
|
|
7047
|
+
+ this.needsCallEnv = true;
|
|
7048
|
+
+ continue;
|
|
7049
|
+
+ }
|
|
7050
|
+
+
|
|
6825
7051
|
+ // amxts: `((player: Player) => boolean) | Requirement[]` - one test, or a
|
|
6826
7052
|
+ // list of objects that each carry one. It is held as the list: a
|
|
6827
7053
|
+ // function given where this type is declared becomes a list of one
|
|
@@ -6899,7 +7125,7 @@ index 157351c..10c3f5c 100644
|
|
|
6899
7125
|
if (!typeIsNull && !nextTypeIsNull) {
|
|
6900
7126
|
if (!suppressErrors) {
|
|
6901
7127
|
this.error(
|
|
6902
|
-
@@ -705,6 +
|
|
7128
|
+
@@ -705,6 +1373,26 @@ export class Parser extends DiagnosticEmitter {
|
|
6903
7129
|
// ... [][]
|
|
6904
7130
|
while (tn.skip(Token.OpenBracket)) {
|
|
6905
7131
|
let bracketStart = tn.tokenPos;
|
|
@@ -6926,7 +7152,7 @@ index 157351c..10c3f5c 100644
|
|
|
6926
7152
|
if (!tn.skip(Token.CloseBracket)) {
|
|
6927
7153
|
if (!suppressErrors) {
|
|
6928
7154
|
this.error(
|
|
6929
|
-
@@ -718,9 +
|
|
7155
|
+
@@ -718,9 +1406,26 @@ export class Parser extends DiagnosticEmitter {
|
|
6930
7156
|
|
|
6931
7157
|
// ...[] | null
|
|
6932
7158
|
let nullable = false;
|
|
@@ -6953,7 +7179,7 @@ index 157351c..10c3f5c 100644
|
|
|
6953
7179
|
} else {
|
|
6954
7180
|
if (!suppressErrors) {
|
|
6955
7181
|
this.error(
|
|
6956
|
-
@@ -737,9 +
|
|
7182
|
+
@@ -737,9 +1442,20 @@ export class Parser extends DiagnosticEmitter {
|
|
6957
7183
|
nullable,
|
|
6958
7184
|
tn.range(startPos, tn.pos)
|
|
6959
7185
|
);
|
|
@@ -6974,7 +7200,7 @@ index 157351c..10c3f5c 100644
|
|
|
6974
7200
|
return type;
|
|
6975
7201
|
}
|
|
6976
7202
|
|
|
6977
|
-
@@ -984,6 +
|
|
7203
|
+
@@ -984,6 +1700,16 @@ export class Parser extends DiagnosticEmitter {
|
|
6978
7204
|
|
|
6979
7205
|
let declarations = new Array<VariableDeclaration>();
|
|
6980
7206
|
do {
|
|
@@ -6991,7 +7217,7 @@ index 157351c..10c3f5c 100644
|
|
|
6991
7217
|
let declaration = this.parseVariableDeclaration(tn, flags, decorators, isFor);
|
|
6992
7218
|
if (!declaration) return null;
|
|
6993
7219
|
declaration.overriddenModuleName = this.currentModuleName;
|
|
6994
|
-
@@ -995,6 +
|
|
7220
|
+
@@ -995,6 +1721,277 @@ export class Parser extends DiagnosticEmitter {
|
|
6995
7221
|
return ret;
|
|
6996
7222
|
}
|
|
6997
7223
|
|
|
@@ -7269,7 +7495,7 @@ index 157351c..10c3f5c 100644
|
|
|
7269
7495
|
parseVariableDeclaration(
|
|
7270
7496
|
tn: Tokenizer,
|
|
7271
7497
|
parentFlags: CommonFlags,
|
|
7272
|
-
@@ -1081,7 +
|
|
7498
|
+
@@ -1081,7 +2078,7 @@ export class Parser extends DiagnosticEmitter {
|
|
7273
7499
|
flags: CommonFlags,
|
|
7274
7500
|
decorators: DecoratorNode[] | null,
|
|
7275
7501
|
startPos: i32
|
|
@@ -7278,7 +7504,7 @@ index 157351c..10c3f5c 100644
|
|
|
7278
7504
|
|
|
7279
7505
|
// at 'enum': Identifier '{' (EnumValueDeclaration (',' EnumValueDeclaration )*)? '}' ';'?
|
|
7280
7506
|
|
|
7281
|
-
@@ -1117,6 +
|
|
7507
|
+
@@ -1117,6 +2114,8 @@ export class Parser extends DiagnosticEmitter {
|
|
7282
7508
|
}
|
|
7283
7509
|
}
|
|
7284
7510
|
}
|
|
@@ -7287,7 +7513,7 @@ index 157351c..10c3f5c 100644
|
|
|
7287
7513
|
let ret = Node.createEnumDeclaration(
|
|
7288
7514
|
identifier,
|
|
7289
7515
|
decorators,
|
|
7290
|
-
@@ -1125,7 +
|
|
7516
|
+
@@ -1125,7 +2124,34 @@ export class Parser extends DiagnosticEmitter {
|
|
7291
7517
|
tn.range(startPos, tn.pos)
|
|
7292
7518
|
);
|
|
7293
7519
|
ret.overriddenModuleName = this.currentModuleName;
|
|
@@ -7323,7 +7549,7 @@ index 157351c..10c3f5c 100644
|
|
|
7323
7549
|
return ret;
|
|
7324
7550
|
}
|
|
7325
7551
|
|
|
7326
|
-
@@ -1235,16 +
|
|
7552
|
+
@@ -1235,16 +2261,41 @@ export class Parser extends DiagnosticEmitter {
|
|
7327
7553
|
);
|
|
7328
7554
|
let extendsType: NamedTypeNode | null = null;
|
|
7329
7555
|
if (tn.skip(Token.Extends)) {
|
|
@@ -7373,7 +7599,7 @@ index 157351c..10c3f5c 100644
|
|
|
7373
7599
|
}
|
|
7374
7600
|
let defaultType: NamedTypeNode | null = null;
|
|
7375
7601
|
if (tn.skip(Token.Equals)) {
|
|
7376
|
-
@@ -1413,9 +
|
|
7602
|
+
@@ -1413,9 +2464,21 @@ export class Parser extends DiagnosticEmitter {
|
|
7377
7603
|
}
|
|
7378
7604
|
isRest = true;
|
|
7379
7605
|
}
|
|
@@ -7398,7 +7624,7 @@ index 157351c..10c3f5c 100644
|
|
|
7398
7624
|
let type: TypeNode | null = null;
|
|
7399
7625
|
if (isOptional = tn.skip(Token.Question)) {
|
|
7400
7626
|
if (isRest) {
|
|
7401
|
-
@@ -1450,6 +
|
|
7627
|
+
@@ -1450,6 +2513,39 @@ export class Parser extends DiagnosticEmitter {
|
|
7402
7628
|
initializer = this.parseExpression(tn, Precedence.Comma + 1);
|
|
7403
7629
|
if (!initializer) return null;
|
|
7404
7630
|
}
|
|
@@ -7438,7 +7664,7 @@ index 157351c..10c3f5c 100644
|
|
|
7438
7664
|
let param = Node.createParameter(
|
|
7439
7665
|
isRest
|
|
7440
7666
|
? ParameterKind.Rest
|
|
7441
|
-
@@ -1462,6 +
|
|
7667
|
+
@@ -1462,6 +2558,7 @@ export class Parser extends DiagnosticEmitter {
|
|
7442
7668
|
Range.join(assert(startRange), tn.range())
|
|
7443
7669
|
);
|
|
7444
7670
|
param.flags |= accessFlags;
|
|
@@ -7446,7 +7672,7 @@ index 157351c..10c3f5c 100644
|
|
|
7446
7672
|
return param;
|
|
7447
7673
|
} else {
|
|
7448
7674
|
this.error(
|
|
7449
|
-
@@ -1477,7 +
|
|
7675
|
+
@@ -1477,7 +2574,7 @@ export class Parser extends DiagnosticEmitter {
|
|
7450
7676
|
flags: CommonFlags,
|
|
7451
7677
|
decorators: DecoratorNode[] | null,
|
|
7452
7678
|
startPos: i32
|
|
@@ -7455,7 +7681,7 @@ index 157351c..10c3f5c 100644
|
|
|
7455
7681
|
|
|
7456
7682
|
// at 'function':
|
|
7457
7683
|
// Identifier
|
|
7458
|
-
@@ -1486,6 +
|
|
7684
|
+
@@ -1486,6 +2583,9 @@ export class Parser extends DiagnosticEmitter {
|
|
7459
7685
|
// '{' Statement* '}'
|
|
7460
7686
|
// ';'?
|
|
7461
7687
|
|
|
@@ -7465,7 +7691,7 @@ index 157351c..10c3f5c 100644
|
|
|
7465
7691
|
if (!tn.skipIdentifier()) {
|
|
7466
7692
|
this.error(
|
|
7467
7693
|
DiagnosticCode.Identifier_expected,
|
|
7468
|
-
@@ -1552,16 +
|
|
7694
|
+
@@ -1552,16 +2652,25 @@ export class Parser extends DiagnosticEmitter {
|
|
7469
7695
|
if (!returnType) return null;
|
|
7470
7696
|
}
|
|
7471
7697
|
|
|
@@ -7499,7 +7725,7 @@ index 157351c..10c3f5c 100644
|
|
|
7499
7725
|
}
|
|
7500
7726
|
|
|
7501
7727
|
let signature = Node.createFunctionType(
|
|
7502
|
-
@@ -1571,6 +
|
|
7728
|
+
@@ -1571,6 +2680,8 @@ export class Parser extends DiagnosticEmitter {
|
|
7503
7729
|
false,
|
|
7504
7730
|
tn.range(signatureStart, tn.pos)
|
|
7505
7731
|
);
|
|
@@ -7508,7 +7734,7 @@ index 157351c..10c3f5c 100644
|
|
|
7508
7734
|
|
|
7509
7735
|
let body: Statement | null = null;
|
|
7510
7736
|
if (tn.skip(Token.OpenBrace)) {
|
|
7511
|
-
@@ -1581,15 +
|
|
7737
|
+
@@ -1581,15 +2692,35 @@ export class Parser extends DiagnosticEmitter {
|
|
7512
7738
|
); // recoverable
|
|
7513
7739
|
}
|
|
7514
7740
|
|
|
@@ -7544,7 +7770,7 @@ index 157351c..10c3f5c 100644
|
|
|
7544
7770
|
let ret = Node.createFunctionDeclaration(
|
|
7545
7771
|
name,
|
|
7546
7772
|
decorators,
|
|
7547
|
-
@@ -1605,6 +
|
|
7773
|
+
@@ -1605,6 +2736,17 @@ export class Parser extends DiagnosticEmitter {
|
|
7548
7774
|
return ret;
|
|
7549
7775
|
}
|
|
7550
7776
|
|
|
@@ -7562,7 +7788,7 @@ index 157351c..10c3f5c 100644
|
|
|
7562
7788
|
parseFunctionExpression(tn: Tokenizer): FunctionExpression | null {
|
|
7563
7789
|
let startPos = tn.tokenPos;
|
|
7564
7790
|
let name: IdentifierExpression;
|
|
7565
|
-
@@ -1641,9 +
|
|
7791
|
+
@@ -1641,9 +2783,13 @@ export class Parser extends DiagnosticEmitter {
|
|
7566
7792
|
|
|
7567
7793
|
// TODO: type parameters? doesn't seem worth it.
|
|
7568
7794
|
|
|
@@ -7576,7 +7802,7 @@ index 157351c..10c3f5c 100644
|
|
|
7576
7802
|
|
|
7577
7803
|
return this.parseFunctionExpressionCommon(tn, name, parameters, this.parseParametersThis, arrowKind, startPos, signatureStart);
|
|
7578
7804
|
}
|
|
7579
|
-
@@ -1685,17 +
|
|
7805
|
+
@@ -1685,17 +2831,32 @@ export class Parser extends DiagnosticEmitter {
|
|
7580
7806
|
false,
|
|
7581
7807
|
tn.range(signatureStart, tn.pos)
|
|
7582
7808
|
);
|
|
@@ -7610,7 +7836,7 @@ index 157351c..10c3f5c 100644
|
|
|
7610
7836
|
this.error(
|
|
7611
7837
|
DiagnosticCode._0_expected,
|
|
7612
7838
|
tn.range(tn.pos), "{"
|
|
7613
|
-
@@ -1704,7 +
|
|
7839
|
+
@@ -1704,7 +2865,26 @@ export class Parser extends DiagnosticEmitter {
|
|
7614
7840
|
}
|
|
7615
7841
|
body = this.parseBlockStatement(tn, false);
|
|
7616
7842
|
}
|
|
@@ -7637,7 +7863,7 @@ index 157351c..10c3f5c 100644
|
|
|
7637
7863
|
|
|
7638
7864
|
let declaration = Node.createFunctionDeclaration(
|
|
7639
7865
|
name,
|
|
7640
|
-
@@ -1724,7 +
|
|
7866
|
+
@@ -1724,7 +2904,7 @@ export class Parser extends DiagnosticEmitter {
|
|
7641
7867
|
flags: CommonFlags,
|
|
7642
7868
|
decorators: DecoratorNode[] | null,
|
|
7643
7869
|
startPos: i32
|
|
@@ -7646,7 +7872,7 @@ index 157351c..10c3f5c 100644
|
|
|
7646
7872
|
|
|
7647
7873
|
// at ('class' | 'interface'):
|
|
7648
7874
|
// Identifier
|
|
7649
|
-
@@ -1852,6 +
|
|
7875
|
+
@@ -1852,6 +3032,52 @@ export class Parser extends DiagnosticEmitter {
|
|
7650
7876
|
}
|
|
7651
7877
|
declaration.range.end = tn.pos;
|
|
7652
7878
|
declaration.overriddenModuleName = this.currentModuleName;
|
|
@@ -7699,7 +7925,7 @@ index 157351c..10c3f5c 100644
|
|
|
7699
7925
|
return declaration;
|
|
7700
7926
|
}
|
|
7701
7927
|
|
|
7702
|
-
@@ -2084,6 +
|
|
7928
|
+
@@ -2084,6 +3310,20 @@ export class Parser extends DiagnosticEmitter {
|
|
7703
7929
|
}
|
|
7704
7930
|
}
|
|
7705
7931
|
|
|
@@ -7720,7 +7946,7 @@ index 157351c..10c3f5c 100644
|
|
|
7720
7946
|
// check if accessor: ('get' | 'set') ^\n Identifier
|
|
7721
7947
|
let state = tn.mark();
|
|
7722
7948
|
let isConstructor = false;
|
|
7723
|
-
@@ -2093,7 +
|
|
7949
|
+
@@ -2093,7 +3333,7 @@ export class Parser extends DiagnosticEmitter {
|
|
7724
7950
|
let isSetter = false;
|
|
7725
7951
|
let setStart = 0;
|
|
7726
7952
|
let setEnd = 0;
|
|
@@ -7729,7 +7955,7 @@ index 157351c..10c3f5c 100644
|
|
|
7729
7955
|
if (tn.skip(Token.Get)) {
|
|
7730
7956
|
if (tn.peek(IdentifierHandling.Prefer) == Token.Identifier && !tn.peekOnNewLine()) {
|
|
7731
7957
|
flags |= CommonFlags.Get;
|
|
7732
|
-
@@ -2126,7 +
|
|
7958
|
+
@@ -2126,7 +3366,7 @@ export class Parser extends DiagnosticEmitter {
|
|
7733
7959
|
} else {
|
|
7734
7960
|
tn.reset(state);
|
|
7735
7961
|
}
|
|
@@ -7738,7 +7964,7 @@ index 157351c..10c3f5c 100644
|
|
|
7738
7964
|
flags |= CommonFlags.Constructor;
|
|
7739
7965
|
isConstructor = true;
|
|
7740
7966
|
if (!startPos) startPos = tn.tokenPos;
|
|
7741
|
-
@@ -2206,15 +
|
|
7967
|
+
@@ -2206,15 +3446,22 @@ export class Parser extends DiagnosticEmitter {
|
|
7742
7968
|
tn.skip(Token.Semicolon);
|
|
7743
7969
|
return retIndex;
|
|
7744
7970
|
}
|
|
@@ -7769,7 +7995,7 @@ index 157351c..10c3f5c 100644
|
|
|
7769
7995
|
}
|
|
7770
7996
|
let typeParameters: TypeParameterNode[] | null = null;
|
|
7771
7997
|
if (tn.skip(Token.LessThan)) {
|
|
7772
|
-
@@ -2299,6 +
|
|
7998
|
+
@@ -2299,6 +3546,7 @@ export class Parser extends DiagnosticEmitter {
|
|
7773
7999
|
}
|
|
7774
8000
|
|
|
7775
8001
|
let returnType: TypeNode | null = null;
|
|
@@ -7777,7 +8003,7 @@ index 157351c..10c3f5c 100644
|
|
|
7777
8003
|
if (tn.skip(Token.Colon)) {
|
|
7778
8004
|
if (name.kind == NodeKind.Constructor) {
|
|
7779
8005
|
this.error(
|
|
7780
|
-
@@ -2313,14 +
|
|
8006
|
+
@@ -2313,14 +3561,20 @@ export class Parser extends DiagnosticEmitter {
|
|
7781
8007
|
}
|
|
7782
8008
|
returnType = this.parseType(tn, isSetter || name.kind == NodeKind.Constructor);
|
|
7783
8009
|
if (!returnType) return null;
|
|
@@ -7804,7 +8030,7 @@ index 157351c..10c3f5c 100644
|
|
|
7804
8030
|
}
|
|
7805
8031
|
|
|
7806
8032
|
let signature = Node.createFunctionType(
|
|
7807
|
-
@@ -2330,6 +
|
|
8033
|
+
@@ -2330,6 +3584,8 @@ export class Parser extends DiagnosticEmitter {
|
|
7808
8034
|
false,
|
|
7809
8035
|
tn.range(signatureStart, tn.pos)
|
|
7810
8036
|
);
|
|
@@ -7813,7 +8039,7 @@ index 157351c..10c3f5c 100644
|
|
|
7813
8039
|
|
|
7814
8040
|
let body: Statement | null = null;
|
|
7815
8041
|
if (tn.skip(Token.OpenBrace)) {
|
|
7816
|
-
@@ -2349,7 +
|
|
8042
|
+
@@ -2349,7 +3605,10 @@ export class Parser extends DiagnosticEmitter {
|
|
7817
8043
|
tn.range(), ";"
|
|
7818
8044
|
); // recoverable
|
|
7819
8045
|
}
|
|
@@ -7824,7 +8050,7 @@ index 157351c..10c3f5c 100644
|
|
|
7824
8050
|
if (!body) return null;
|
|
7825
8051
|
} else if (!isInterface && !(flags & (CommonFlags.Ambient | CommonFlags.Abstract))) {
|
|
7826
8052
|
this.error(
|
|
7827
|
-
@@ -2358,6 +
|
|
8053
|
+
@@ -2358,6 +3617,9 @@ export class Parser extends DiagnosticEmitter {
|
|
7828
8054
|
); // recoverable
|
|
7829
8055
|
}
|
|
7830
8056
|
|
|
@@ -7834,7 +8060,7 @@ index 157351c..10c3f5c 100644
|
|
|
7834
8060
|
let retMethod = Node.createMethodDeclaration(
|
|
7835
8061
|
name,
|
|
7836
8062
|
decorators,
|
|
7837
|
-
@@ -2415,23 +
|
|
8063
|
+
@@ -2415,23 +3677,21 @@ export class Parser extends DiagnosticEmitter {
|
|
7838
8064
|
}
|
|
7839
8065
|
|
|
7840
8066
|
let type: TypeNode | null = null;
|
|
@@ -7866,7 +8092,7 @@ index 157351c..10c3f5c 100644
|
|
|
7866
8092
|
}
|
|
7867
8093
|
let initializer: Expression | null = null;
|
|
7868
8094
|
if (tn.skip(Token.Equals)) {
|
|
7869
|
-
@@ -2450,6 +
|
|
8095
|
+
@@ -2450,6 +3710,43 @@ export class Parser extends DiagnosticEmitter {
|
|
7870
8096
|
);
|
|
7871
8097
|
}
|
|
7872
8098
|
}
|
|
@@ -7910,7 +8136,7 @@ index 157351c..10c3f5c 100644
|
|
|
7910
8136
|
let range = tn.range(startPos, tn.pos);
|
|
7911
8137
|
if ((flags & CommonFlags.DefinitelyAssigned) != 0 && (isInterface || (flags & CommonFlags.Ambient) != 0)) {
|
|
7912
8138
|
this.error(
|
|
7913
|
-
@@ -2465,6 +
|
|
8139
|
+
@@ -2465,6 +3762,7 @@ export class Parser extends DiagnosticEmitter {
|
|
7914
8140
|
initializer,
|
|
7915
8141
|
range
|
|
7916
8142
|
);
|
|
@@ -7918,7 +8144,7 @@ index 157351c..10c3f5c 100644
|
|
|
7918
8144
|
if (!(isInterface && tn.skip(Token.Comma))) {
|
|
7919
8145
|
tn.skip(Token.Semicolon);
|
|
7920
8146
|
}
|
|
7921
|
-
@@ -2473,6 +
|
|
8147
|
+
@@ -2473,6 +3771,208 @@ export class Parser extends DiagnosticEmitter {
|
|
7922
8148
|
return null;
|
|
7923
8149
|
}
|
|
7924
8150
|
|
|
@@ -8040,6 +8266,14 @@ index 157351c..10c3f5c 100644
|
|
|
8040
8266
|
+ for (let i = 0, k = node.bodyStatements.length; i < k; ++i) this.collectReturns(node.bodyStatements[i], values, locals);
|
|
8041
8267
|
+ let catchStatements = node.catchStatements;
|
|
8042
8268
|
+ if (catchStatements) {
|
|
8269
|
+
+ // amxts: `catch (error) { return error.name; }` - the caught value
|
|
8270
|
+
+ // is an Error, as Compiler.compileTryStatement declares it.
|
|
8271
|
+
+ let caught = node.catchVariable;
|
|
8272
|
+
+ if (caught && !locals.has(caught.text)) {
|
|
8273
|
+
+ let range = caught.range;
|
|
8274
|
+
+ let type = Node.createNamedType(Node.createSimpleTypeName("Error", range), null, false, range);
|
|
8275
|
+
+ locals.set(caught.text, Node.createVariableDeclaration(caught, null, CommonFlags.Let, type, null, range));
|
|
8276
|
+
+ }
|
|
8043
8277
|
+ for (let i = 0, k = catchStatements.length; i < k; ++i) this.collectReturns(catchStatements[i], values, locals);
|
|
8044
8278
|
+ }
|
|
8045
8279
|
+ let finallyStatements = node.finallyStatements;
|
|
@@ -8119,7 +8353,7 @@ index 157351c..10c3f5c 100644
|
|
|
8119
8353
|
parseIndexSignature(
|
|
8120
8354
|
tn: Tokenizer,
|
|
8121
8355
|
flags: CommonFlags,
|
|
8122
|
-
@@ -2490,8 +
|
|
8356
|
+
@@ -2490,8 +3990,9 @@ export class Parser extends DiagnosticEmitter {
|
|
8123
8357
|
|
|
8124
8358
|
let start = tn.tokenPos;
|
|
8125
8359
|
if (tn.skipIdentifier()) {
|
|
@@ -8131,7 +8365,7 @@ index 157351c..10c3f5c 100644
|
|
|
8131
8365
|
if (tn.skip(Token.Colon)) {
|
|
8132
8366
|
let keyType = this.parseType(tn);
|
|
8133
8367
|
if (!keyType) return null;
|
|
8134
|
-
@@ -2506,13 +
|
|
8368
|
+
@@ -2506,13 +4007,6 @@ export class Parser extends DiagnosticEmitter {
|
|
8135
8369
|
if (tn.skip(Token.Colon)) {
|
|
8136
8370
|
let valueType = this.parseType(tn);
|
|
8137
8371
|
if (!valueType) return null;
|
|
@@ -8145,7 +8379,7 @@ index 157351c..10c3f5c 100644
|
|
|
8145
8379
|
return Node.createIndexSignature(<NamedTypeNode>keyType, valueType, flags, tn.range(start, tn.pos));
|
|
8146
8380
|
} else {
|
|
8147
8381
|
this.error(
|
|
8148
|
-
@@ -2532,11 +
|
|
8382
|
+
@@ -2532,11 +4026,6 @@ export class Parser extends DiagnosticEmitter {
|
|
8149
8383
|
tn.range(), ":"
|
|
8150
8384
|
);
|
|
8151
8385
|
}
|
|
@@ -8157,7 +8391,7 @@ index 157351c..10c3f5c 100644
|
|
|
8157
8391
|
}
|
|
8158
8392
|
} else {
|
|
8159
8393
|
this.error(
|
|
8160
|
-
@@ -2770,6 +
|
|
8394
|
+
@@ -2770,6 +4259,18 @@ export class Parser extends DiagnosticEmitter {
|
|
8161
8395
|
let members: ImportDeclaration[] | null = null;
|
|
8162
8396
|
let namespaceName: IdentifierExpression | null = null;
|
|
8163
8397
|
let skipFrom = false;
|
|
@@ -8176,7 +8410,7 @@ index 157351c..10c3f5c 100644
|
|
|
8176
8410
|
if (tn.skip(Token.OpenBrace)) { // import { ... } from "file"
|
|
8177
8411
|
members = new Array();
|
|
8178
8412
|
while (!tn.skip(Token.CloseBrace)) {
|
|
8179
|
-
@@ -3026,6 +
|
|
8413
|
+
@@ -3026,6 +4527,15 @@ export class Parser extends DiagnosticEmitter {
|
|
8180
8414
|
// fall-through
|
|
8181
8415
|
}
|
|
8182
8416
|
default: {
|
|
@@ -8192,7 +8426,7 @@ index 157351c..10c3f5c 100644
|
|
|
8192
8426
|
tn.reset(state);
|
|
8193
8427
|
statement = this.parseExpressionStatement(tn);
|
|
8194
8428
|
break;
|
|
8195
|
-
@@ -3153,17 +
|
|
8429
|
+
@@ -3153,17 +4663,114 @@ export class Parser extends DiagnosticEmitter {
|
|
8196
8430
|
return ret;
|
|
8197
8431
|
}
|
|
8198
8432
|
|
|
@@ -8309,7 +8543,7 @@ index 157351c..10c3f5c 100644
|
|
|
8309
8543
|
if (tn.skip(Token.Const)) {
|
|
8310
8544
|
initializer = this.parseVariable(tn, CommonFlags.Const, null, tn.tokenPos, true);
|
|
8311
8545
|
} else if (tn.skip(Token.Let)) {
|
|
8312
|
-
@@ -3291,7 +
|
|
8546
|
+
@@ -3291,7 +4898,7 @@ export class Parser extends DiagnosticEmitter {
|
|
8313
8547
|
tn: Tokenizer,
|
|
8314
8548
|
startPos: i32,
|
|
8315
8549
|
variable: Statement,
|
|
@@ -8318,7 +8552,7 @@ index 157351c..10c3f5c 100644
|
|
|
8318
8552
|
|
|
8319
8553
|
// at 'of': Expression ')' Statement
|
|
8320
8554
|
|
|
8321
|
-
@@ -3308,15 +
|
|
8555
|
+
@@ -3308,15 +4915,87 @@ export class Parser extends DiagnosticEmitter {
|
|
8322
8556
|
|
|
8323
8557
|
let statement = this.parseStatement(tn);
|
|
8324
8558
|
if (!statement) return null;
|
|
@@ -8407,7 +8641,7 @@ index 157351c..10c3f5c 100644
|
|
|
8407
8641
|
parseIfStatement(
|
|
8408
8642
|
tn: Tokenizer
|
|
8409
8643
|
): IfStatement | null {
|
|
8410
|
-
@@ -3496,27 +
|
|
8644
|
+
@@ -3496,27 +5175,27 @@ export class Parser extends DiagnosticEmitter {
|
|
8411
8645
|
let catchStatements: Statement[] | null = null;
|
|
8412
8646
|
let finallyStatements: Statement[] | null = null;
|
|
8413
8647
|
if (tn.skip(Token.Catch)) {
|
|
@@ -8456,7 +8690,7 @@ index 157351c..10c3f5c 100644
|
|
|
8456
8690
|
}
|
|
8457
8691
|
if (!tn.skip(Token.OpenBrace)) {
|
|
8458
8692
|
this.error(
|
|
8459
|
-
@@ -3561,6 +
|
|
8693
|
+
@@ -3561,6 +5240,9 @@ export class Parser extends DiagnosticEmitter {
|
|
8460
8694
|
finallyStatements,
|
|
8461
8695
|
tn.range(startPos, tn.pos)
|
|
8462
8696
|
);
|
|
@@ -8466,7 +8700,7 @@ index 157351c..10c3f5c 100644
|
|
|
8466
8700
|
tn.skip(Token.Semicolon);
|
|
8467
8701
|
return ret;
|
|
8468
8702
|
} else {
|
|
8469
|
-
@@ -3608,6 +
|
|
8703
|
+
@@ -3608,6 +5290,11 @@ export class Parser extends DiagnosticEmitter {
|
|
8470
8704
|
type,
|
|
8471
8705
|
tn.range(startPos, tn.pos)
|
|
8472
8706
|
);
|
|
@@ -8478,7 +8712,7 @@ index 157351c..10c3f5c 100644
|
|
|
8478
8712
|
tn.skip(Token.Semicolon);
|
|
8479
8713
|
ret.overriddenModuleName = this.currentModuleName;
|
|
8480
8714
|
return ret;
|
|
8481
|
-
@@ -3694,6 +
|
|
8715
|
+
@@ -3694,6 +5381,19 @@ export class Parser extends DiagnosticEmitter {
|
|
8482
8716
|
): Expression | null {
|
|
8483
8717
|
let token = tn.next(IdentifierHandling.Prefer);
|
|
8484
8718
|
let startPos = tn.tokenPos;
|
|
@@ -8498,7 +8732,7 @@ index 157351c..10c3f5c 100644
|
|
|
8498
8732
|
switch (token) {
|
|
8499
8733
|
|
|
8500
8734
|
// TODO: SpreadExpression, YieldExpression
|
|
8501
|
-
@@ -3712,6 +
|
|
8735
|
+
@@ -3712,6 +5412,51 @@ export class Parser extends DiagnosticEmitter {
|
|
8502
8736
|
if (!operand) return null;
|
|
8503
8737
|
return Node.createUnaryPrefixExpression(token, operand, tn.range(startPos, tn.pos));
|
|
8504
8738
|
}
|
|
@@ -8550,7 +8784,7 @@ index 157351c..10c3f5c 100644
|
|
|
8550
8784
|
case Token.Plus_Plus:
|
|
8551
8785
|
case Token.Minus_Minus: {
|
|
8552
8786
|
let operand = this.parseExpression(tn, Precedence.UnaryPrefix);
|
|
8553
|
-
@@ -3752,6 +
|
|
8787
|
+
@@ -3752,6 +5497,9 @@ export class Parser extends DiagnosticEmitter {
|
|
8554
8788
|
} else {
|
|
8555
8789
|
arguments_ = []; // new Type;
|
|
8556
8790
|
}
|
|
@@ -8560,7 +8794,7 @@ index 157351c..10c3f5c 100644
|
|
|
8560
8794
|
return Node.createNewExpression(
|
|
8561
8795
|
typeName,
|
|
8562
8796
|
typeArguments,
|
|
8563
|
-
@@ -3790,6 +
|
|
8797
|
+
@@ -3790,6 +5538,24 @@ export class Parser extends DiagnosticEmitter {
|
|
8564
8798
|
tn.reset(state);
|
|
8565
8799
|
return this.parseFunctionExpression(tn);
|
|
8566
8800
|
}
|
|
@@ -8585,7 +8819,7 @@ index 157351c..10c3f5c 100644
|
|
|
8585
8819
|
// can be both
|
|
8586
8820
|
case Token.Identifier: {
|
|
8587
8821
|
tn.readIdentifier();
|
|
8588
|
-
@@ -3896,6 +
|
|
8822
|
+
@@ -3896,6 +5662,25 @@ export class Parser extends DiagnosticEmitter {
|
|
8589
8823
|
let values = new Array<Expression>();
|
|
8590
8824
|
let name: IdentifierExpression;
|
|
8591
8825
|
while (!tn.skip(Token.CloseBrace)) {
|
|
@@ -8611,7 +8845,7 @@ index 157351c..10c3f5c 100644
|
|
|
8611
8845
|
if (!tn.skipIdentifier()) {
|
|
8612
8846
|
if (!tn.skip(Token.StringLiteral)) {
|
|
8613
8847
|
this.error(
|
|
8614
|
-
@@ -3914,6 +
|
|
8848
|
+
@@ -3914,6 +5699,17 @@ export class Parser extends DiagnosticEmitter {
|
|
8615
8849
|
let value = this.parseExpression(tn, Precedence.Comma + 1);
|
|
8616
8850
|
if (!value) return null;
|
|
8617
8851
|
values.push(value);
|
|
@@ -8629,7 +8863,7 @@ index 157351c..10c3f5c 100644
|
|
|
8629
8863
|
} else if (!name.isQuoted) {
|
|
8630
8864
|
values.push(name);
|
|
8631
8865
|
} else {
|
|
8632
|
-
@@ -3935,7 +
|
|
8866
|
+
@@ -3935,7 +5731,10 @@ export class Parser extends DiagnosticEmitter {
|
|
8633
8867
|
}
|
|
8634
8868
|
}
|
|
8635
8869
|
}
|
|
@@ -8641,7 +8875,7 @@ index 157351c..10c3f5c 100644
|
|
|
8641
8875
|
}
|
|
8642
8876
|
// AssertionExpression (unary prefix)
|
|
8643
8877
|
case Token.LessThan: {
|
|
8644
|
-
@@ -4129,20 +
|
|
8878
|
+
@@ -4129,20 +5928,32 @@ export class Parser extends DiagnosticEmitter {
|
|
8645
8879
|
// see: http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm#climbing
|
|
8646
8880
|
let nextPrecedence: Precedence;
|
|
8647
8881
|
while (
|
|
@@ -8681,7 +8915,7 @@ index 157351c..10c3f5c 100644
|
|
|
8681
8915
|
} else {
|
|
8682
8916
|
let toType = this.parseType(tn); // reports
|
|
8683
8917
|
if (!toType) return null;
|
|
8684
|
-
@@ -4281,6 +
|
|
8918
|
+
@@ -4281,6 +6092,44 @@ export class Parser extends DiagnosticEmitter {
|
|
8685
8919
|
}
|
|
8686
8920
|
break;
|
|
8687
8921
|
}
|
|
@@ -8726,7 +8960,7 @@ index 157351c..10c3f5c 100644
|
|
|
8726
8960
|
// BinaryExpression (right associative)
|
|
8727
8961
|
case Token.Equals:
|
|
8728
8962
|
case Token.Plus_Equals:
|
|
8729
|
-
@@ -4295,6 +
|
|
8963
|
+
@@ -4295,6 +6144,7 @@ export class Parser extends DiagnosticEmitter {
|
|
8730
8964
|
case Token.Ampersand_Equals:
|
|
8731
8965
|
case Token.Caret_Equals:
|
|
8732
8966
|
case Token.Bar_Equals:
|
|
@@ -8734,7 +8968,7 @@ index 157351c..10c3f5c 100644
|
|
|
8734
8968
|
case Token.Asterisk_Asterisk: {
|
|
8735
8969
|
let next = this.parseExpression(tn, nextPrecedence);
|
|
8736
8970
|
if (!next) return null;
|
|
8737
|
-
@@ -4323,6 +
|
|
8971
|
+
@@ -4323,6 +6173,7 @@ export class Parser extends DiagnosticEmitter {
|
|
8738
8972
|
case Token.Caret:
|
|
8739
8973
|
case Token.Ampersand_Ampersand:
|
|
8740
8974
|
case Token.Bar_Bar:
|
|
@@ -8742,7 +8976,7 @@ index 157351c..10c3f5c 100644
|
|
|
8742
8976
|
case Token.In: {
|
|
8743
8977
|
let next = this.parseExpression(tn, nextPrecedence + 1);
|
|
8744
8978
|
if (!next) return null;
|
|
8745
|
-
@@ -4335,6 +
|
|
8979
|
+
@@ -4335,6 +6186,26 @@ export class Parser extends DiagnosticEmitter {
|
|
8746
8980
|
return expr;
|
|
8747
8981
|
}
|
|
8748
8982
|
|
|
@@ -8769,7 +9003,7 @@ index 157351c..10c3f5c 100644
|
|
|
8769
9003
|
private parseTemplateLiteral(tn: Tokenizer, tag: Expression | null = null): Expression | null {
|
|
8770
9004
|
// at '`': ... '`'
|
|
8771
9005
|
let startPos = tag ? tag.range.start : tn.tokenPos;
|
|
8772
|
-
@@ -4569,9 +
|
|
9006
|
+
@@ -4569,9 +6440,11 @@ function determinePrecedence(kind: Token): Precedence {
|
|
8773
9007
|
case Token.GreaterThan_GreaterThan_GreaterThan_Equals:
|
|
8774
9008
|
case Token.Ampersand_Equals:
|
|
8775
9009
|
case Token.Caret_Equals:
|
|
@@ -8783,7 +9017,7 @@ index 157351c..10c3f5c 100644
|
|
|
8783
9017
|
case Token.Ampersand_Ampersand: return Precedence.LogicalAnd;
|
|
8784
9018
|
case Token.Bar: return Precedence.BitwiseOr;
|
|
8785
9019
|
case Token.Caret: return Precedence.BitwiseXor;
|
|
8786
|
-
@@ -4599,6 +
|
|
9020
|
+
@@ -4599,6 +6472,7 @@ function determinePrecedence(kind: Token): Precedence {
|
|
8787
9021
|
case Token.Plus_Plus:
|
|
8788
9022
|
case Token.Minus_Minus: return Precedence.UnaryPostfix;
|
|
8789
9023
|
case Token.Dot:
|
|
@@ -8791,7 +9025,7 @@ index 157351c..10c3f5c 100644
|
|
|
8791
9025
|
case Token.OpenBracket:
|
|
8792
9026
|
case Token.Exclamation: return Precedence.MemberAccess;
|
|
8793
9027
|
}
|
|
8794
|
-
@@ -4640,3 +
|
|
9028
|
+
@@ -4640,3 +6514,72 @@ function isCircularTypeAlias(name: string, type: TypeNode): bool {
|
|
8795
9029
|
}
|
|
8796
9030
|
return false;
|
|
8797
9031
|
}
|
|
@@ -9156,7 +9390,7 @@ index f5d9b7c..81527b0 100644
|
|
|
9156
9390
|
+ }
|
|
9157
9391
|
+}
|
|
9158
9392
|
diff --git a/src/resolver.ts b/src/resolver.ts
|
|
9159
|
-
index 9576a47..
|
|
9393
|
+
index 9576a47..3aa2e32 100644
|
|
9160
9394
|
--- a/src/resolver.ts
|
|
9161
9395
|
+++ b/src/resolver.ts
|
|
9162
9396
|
@@ -36,7 +36,9 @@ import {
|
|
@@ -9463,7 +9697,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9463
9697
|
if (!argumentExpression) {
|
|
9464
9698
|
// optional but not have initializer should be handled in the other place
|
|
9465
9699
|
if (parameterNodes[i].parameterKind == ParameterKind.Optional) {
|
|
9466
|
-
@@ -743,8 +913,
|
|
9700
|
+
@@ -743,8 +913,43 @@ export class Resolver extends DiagnosticEmitter {
|
|
9467
9701
|
if (parameterNodes[i].parameterKind == ParameterKind.Rest) {
|
|
9468
9702
|
typeNode = (<NamedTypeNode> typeNode).typeArguments![0];
|
|
9469
9703
|
}
|
|
@@ -9475,6 +9709,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9475
9709
|
+ (<LiteralExpression>argumentExpression).literalKind == LiteralKind.Object &&
|
|
9476
9710
|
+ !(<ObjectLiteralExpression>argumentExpression).inferredType
|
|
9477
9711
|
+ ) continue;
|
|
9712
|
+
+ if (this.propagateTupleList(typeNode, argumentExpression, ctxFlow, prototype, contextualTypeArguments, typeParameterNames)) continue;
|
|
9478
9713
|
if (typeNode.hasGenericComponent(typeParameterNodes)) {
|
|
9479
9714
|
- let type = this.resolveExpression(argumentExpression, ctxFlow, Type.auto, ReportMode.Swallow);
|
|
9480
9715
|
+ // amxts: an arrow with untyped parameters needs a context to resolve
|
|
@@ -9484,9 +9719,18 @@ index 9576a47..d1fd13d 100644
|
|
|
9484
9719
|
+ let argumentContext = Type.auto;
|
|
9485
9720
|
+ if (argumentExpression.kind == NodeKind.Function && typeNode.kind == NodeKind.FunctionType) {
|
|
9486
9721
|
+ let functionNode = <FunctionTypeNode>typeNode;
|
|
9722
|
+
+ // amxts: a parameter typed by a generic class of what is still being
|
|
9723
|
+
+ // inferred - `MenuContext<Data>` in `new Menu(({ player }) => ...)` -
|
|
9724
|
+
+ // stays unknown, and the type argument takes its default: a class of
|
|
9725
|
+
+ // `auto` is no type, and resolving it comes back to this very node
|
|
9726
|
+
+ // through the class's own members (Menu<Data> holds
|
|
9727
|
+
+ // MenuContext<Data>), "Recursive types".
|
|
9728
|
+
+ let unbound = typeParameterNodes.filter(each => contextualTypeArguments.get(each.name.text) == Type.auto);
|
|
9487
9729
|
+ let known = new Array<Type>();
|
|
9488
9730
|
+ for (let j = 0, l = functionNode.parameters.length; j < l; ++j) {
|
|
9489
|
-
+ let
|
|
9731
|
+
+ let parameterType = functionNode.parameters[j].type;
|
|
9732
|
+
+ if (parameterType.kind == NodeKind.NamedType && (<NamedTypeNode>parameterType).hasTypeArguments && parameterType.hasGenericComponent(unbound)) break;
|
|
9733
|
+
+ let known1 = this.resolveType(parameterType, null, prototype, contextualTypeArguments, ReportMode.Swallow);
|
|
9490
9734
|
+ if (!known1) break;
|
|
9491
9735
|
+ known.push(known1);
|
|
9492
9736
|
+ }
|
|
@@ -9498,7 +9742,53 @@ index 9576a47..d1fd13d 100644
|
|
|
9498
9742
|
if (type) {
|
|
9499
9743
|
this.propagateInferredGenericTypes(
|
|
9500
9744
|
typeNode,
|
|
9501
|
-
@@ -
|
|
9745
|
+
@@ -817,6 +1022,45 @@ export class Resolver extends DiagnosticEmitter {
|
|
9746
|
+
}
|
|
9747
|
+
|
|
9748
|
+
/** Updates contextual types with a possibly encapsulated inferred type. */
|
|
9749
|
+
+ /**
|
|
9750
|
+
+ * amxts: what an array literal of array literals says of a parameter of a
|
|
9751
|
+
+ * list of tuples, `[K, V][]`, one element at a time: `new Map([["a", 1],
|
|
9752
|
+
+ * ["b", 2]])` is a Map of string and number. Such a literal is a list of
|
|
9753
|
+
+ * tuples only where one goes, and alone it has no type to infer from.
|
|
9754
|
+
+ * False when the parameter or the argument is not of that kind.
|
|
9755
|
+
+ */
|
|
9756
|
+
+ private propagateTupleList(
|
|
9757
|
+
+ typeNode: TypeNode,
|
|
9758
|
+
+ argument: Expression,
|
|
9759
|
+
+ ctxFlow: Flow,
|
|
9760
|
+
+ ctxElement: Element,
|
|
9761
|
+
+ ctxTypes: Map<string,Type>,
|
|
9762
|
+
+ typeParameterNames: Set<string>
|
|
9763
|
+
+ ): bool {
|
|
9764
|
+
+ if (
|
|
9765
|
+
+ typeNode.kind != NodeKind.NamedType ||
|
|
9766
|
+
+ argument.kind != NodeKind.Literal ||
|
|
9767
|
+
+ (<LiteralExpression>argument).literalKind != LiteralKind.Array
|
|
9768
|
+
+ ) return false;
|
|
9769
|
+
+ let list = <NamedTypeNode>typeNode;
|
|
9770
|
+
+ let items = list.typeArguments;
|
|
9771
|
+
+ if (list.name.identifier.text != "Array" || !items || items.length != 1 || items[0].kind != NodeKind.NamedType) return false;
|
|
9772
|
+
+ let tuple = <NamedTypeNode>items[0];
|
|
9773
|
+
+ let elementNodes = tuple.typeArguments;
|
|
9774
|
+
+ if (!tuple.name.identifier.text.startsWith("__Tuple") || !elementNodes) return false;
|
|
9775
|
+
+ let literals = (<ArrayLiteralExpression>argument).elementExpressions;
|
|
9776
|
+
+ for (let i = 0, k = literals.length; i < k; ++i) {
|
|
9777
|
+
+ let literal = literals[i];
|
|
9778
|
+
+ if (literal.kind != NodeKind.Literal || (<LiteralExpression>literal).literalKind != LiteralKind.Array) continue;
|
|
9779
|
+
+ let values = (<ArrayLiteralExpression>literal).elementExpressions;
|
|
9780
|
+
+ for (let j = 0, l = min(values.length, elementNodes.length); j < l; ++j) {
|
|
9781
|
+
+ let type = this.resolveExpression(values[j], ctxFlow, Type.auto, ReportMode.Swallow);
|
|
9782
|
+
+ if (type) this.propagateInferredGenericTypes(elementNodes[j], type, ctxElement, ctxTypes, typeParameterNames);
|
|
9783
|
+
+ }
|
|
9784
|
+
+ }
|
|
9785
|
+
+ return true;
|
|
9786
|
+
+ }
|
|
9787
|
+
+
|
|
9788
|
+
private propagateInferredGenericTypes(
|
|
9789
|
+
/** The inferred type node. */
|
|
9790
|
+
node: TypeNode,
|
|
9791
|
+
@@ -915,7 +1159,11 @@ export class Resolver extends DiagnosticEmitter {
|
|
9502
9792
|
let classReference = type.getClassOrWrapper(this.program);
|
|
9503
9793
|
if (classReference) {
|
|
9504
9794
|
let wrappedType = classReference.wrappedType;
|
|
@@ -9511,7 +9801,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9511
9801
|
}
|
|
9512
9802
|
return type;
|
|
9513
9803
|
}
|
|
9514
|
-
@@ -1067,8 +
|
|
9804
|
+
@@ -1067,8 +1315,10 @@ export class Resolver extends DiagnosticEmitter {
|
|
9515
9805
|
const resolvingExpressions = this.resolvingExpressions;
|
|
9516
9806
|
if (resolvingExpressions.has(node)) return null;
|
|
9517
9807
|
resolvingExpressions.add(node);
|
|
@@ -9523,7 +9813,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9523
9813
|
return resolved;
|
|
9524
9814
|
}
|
|
9525
9815
|
|
|
9526
|
-
@@ -1253,6 +
|
|
9816
|
+
@@ -1253,6 +1503,19 @@ export class Resolver extends DiagnosticEmitter {
|
|
9527
9817
|
/** How to proceed with eventual diagnostics. */
|
|
9528
9818
|
reportMode: ReportMode = ReportMode.Report
|
|
9529
9819
|
): Type | null {
|
|
@@ -9543,7 +9833,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9543
9833
|
switch (node.kind) {
|
|
9544
9834
|
case NodeKind.True:
|
|
9545
9835
|
case NodeKind.False: return Type.bool;
|
|
9546
|
-
@@ -1434,6 +
|
|
9836
|
+
@@ -1434,6 +1697,12 @@ export class Resolver extends DiagnosticEmitter {
|
|
9547
9837
|
}
|
|
9548
9838
|
}
|
|
9549
9839
|
|
|
@@ -9556,7 +9846,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9556
9846
|
// Look up the member within
|
|
9557
9847
|
switch (target.kind) {
|
|
9558
9848
|
case ElementKind.ClassPrototype:
|
|
9559
|
-
@@ -1544,6 +
|
|
9849
|
+
@@ -1544,6 +1813,9 @@ export class Resolver extends DiagnosticEmitter {
|
|
9560
9850
|
/** How to proceed with eventual diagnostics. */
|
|
9561
9851
|
reportMode: ReportMode = ReportMode.Report
|
|
9562
9852
|
): Element | null {
|
|
@@ -9566,7 +9856,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9566
9856
|
let targetExpression = node.expression;
|
|
9567
9857
|
let targetType = this.resolveExpression(targetExpression, ctxFlow, ctxType, reportMode);
|
|
9568
9858
|
if (!targetType) return null;
|
|
9569
|
-
@@ -1579,6 +
|
|
9859
|
+
@@ -1579,6 +1851,8 @@ export class Resolver extends DiagnosticEmitter {
|
|
9570
9860
|
/** How to proceed with eventual diagnostics. */
|
|
9571
9861
|
reportMode: ReportMode = ReportMode.Report
|
|
9572
9862
|
): Type | null {
|
|
@@ -9575,7 +9865,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9575
9865
|
let element = this.lookupElementAccessExpression(node, ctxFlow, ctxType, reportMode);
|
|
9576
9866
|
if (!element) return null;
|
|
9577
9867
|
let type = this.getTypeOfElement(element);
|
|
9578
|
-
@@ -1624,6 +
|
|
9868
|
+
@@ -1624,6 +1898,9 @@ export class Resolver extends DiagnosticEmitter {
|
|
9579
9869
|
}
|
|
9580
9870
|
intValue = i64_neg(intValue);
|
|
9581
9871
|
}
|
|
@@ -9585,7 +9875,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9585
9875
|
if (ctxType.isValue) {
|
|
9586
9876
|
// compile to contextual type if matching
|
|
9587
9877
|
switch (ctxType.kind) {
|
|
9588
|
-
@@ -1675,6 +
|
|
9878
|
+
@@ -1675,6 +1952,13 @@ export class Resolver extends DiagnosticEmitter {
|
|
9589
9879
|
case TypeKind.F64: return Type.f64;
|
|
9590
9880
|
}
|
|
9591
9881
|
}
|
|
@@ -9599,7 +9889,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9599
9889
|
// otherwise compile to best fitting type
|
|
9600
9890
|
if (i64_is_i32(intValue)) return Type.i32;
|
|
9601
9891
|
if (i64_is_u32(intValue)) return Type.u32;
|
|
9602
|
-
@@ -1895,6 +
|
|
9892
|
+
@@ -1895,6 +2179,9 @@ export class Resolver extends DiagnosticEmitter {
|
|
9603
9893
|
case Token.TypeOf: {
|
|
9604
9894
|
return this.program.stringInstance.type;
|
|
9605
9895
|
}
|
|
@@ -9609,7 +9899,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9609
9899
|
default: assert(false);
|
|
9610
9900
|
}
|
|
9611
9901
|
return null;
|
|
9612
|
-
@@ -2018,7 +
|
|
9902
|
+
@@ -2018,7 +2305,8 @@ export class Resolver extends DiagnosticEmitter {
|
|
9613
9903
|
case Token.GreaterThan_GreaterThan_GreaterThan_Equals:
|
|
9614
9904
|
case Token.Ampersand_Equals:
|
|
9615
9905
|
case Token.Bar_Equals:
|
|
@@ -9619,7 +9909,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9619
9909
|
return this.resolveExpression(left, ctxFlow, ctxType, reportMode);
|
|
9620
9910
|
}
|
|
9621
9911
|
|
|
9622
|
-
@@ -2091,6 +
|
|
9912
|
+
@@ -2091,6 +2379,11 @@ export class Resolver extends DiagnosticEmitter {
|
|
9623
9913
|
}
|
|
9624
9914
|
let rightType = this.resolveExpression(right, ctxFlow, leftType, reportMode);
|
|
9625
9915
|
if (!rightType) return null;
|
|
@@ -9631,7 +9921,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9631
9921
|
let commonType = Type.commonType(leftType, rightType, ctxType);
|
|
9632
9922
|
if (!commonType) {
|
|
9633
9923
|
if (reportMode == ReportMode.Report) {
|
|
9634
|
-
@@ -2100,6 +
|
|
9924
|
+
@@ -2100,6 +2393,14 @@ export class Resolver extends DiagnosticEmitter {
|
|
9635
9925
|
);
|
|
9636
9926
|
}
|
|
9637
9927
|
}
|
|
@@ -9646,7 +9936,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9646
9936
|
return commonType;
|
|
9647
9937
|
}
|
|
9648
9938
|
|
|
9649
|
-
@@ -2115,6 +
|
|
9939
|
+
@@ -2115,6 +2416,10 @@ export class Resolver extends DiagnosticEmitter {
|
|
9650
9940
|
let overload = classReference.lookupOverload(OperatorKind.fromBinaryToken(operator));
|
|
9651
9941
|
if (overload) return overload.signature.returnType;
|
|
9652
9942
|
}
|
|
@@ -9657,7 +9947,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9657
9947
|
if (!leftType.isIntegerValue) {
|
|
9658
9948
|
if (reportMode == ReportMode.Report) {
|
|
9659
9949
|
this.error(
|
|
9660
|
-
@@ -2141,6 +
|
|
9950
|
+
@@ -2141,6 +2446,9 @@ export class Resolver extends DiagnosticEmitter {
|
|
9661
9951
|
}
|
|
9662
9952
|
let rightType = this.resolveExpression(right, ctxFlow, ctxType, reportMode);
|
|
9663
9953
|
if (!rightType) return null;
|
|
@@ -9667,7 +9957,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9667
9957
|
let commonType = Type.commonType(leftType, rightType, ctxType);
|
|
9668
9958
|
if (!commonType || !commonType.isIntegerValue) {
|
|
9669
9959
|
if (reportMode == ReportMode.Report) {
|
|
9670
|
-
@@ -2191,6 +
|
|
9960
|
+
@@ -2191,6 +2499,25 @@ export class Resolver extends DiagnosticEmitter {
|
|
9671
9961
|
? commonType
|
|
9672
9962
|
: commonType.nonNullableType;
|
|
9673
9963
|
}
|
|
@@ -9693,7 +9983,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9693
9983
|
}
|
|
9694
9984
|
assert(false);
|
|
9695
9985
|
return null;
|
|
9696
|
-
@@ -2215,6 +
|
|
9986
|
+
@@ -2215,6 +2542,15 @@ export class Resolver extends DiagnosticEmitter {
|
|
9697
9987
|
return thisLocal;
|
|
9698
9988
|
}
|
|
9699
9989
|
}
|
|
@@ -9709,7 +9999,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9709
9999
|
let parent = ctxFlow.sourceFunction.parent;
|
|
9710
10000
|
if (parent) {
|
|
9711
10001
|
this.currentThisExpression = null;
|
|
9712
|
-
@@ -2274,6 +
|
|
10002
|
+
@@ -2274,6 +2610,16 @@ export class Resolver extends DiagnosticEmitter {
|
|
9713
10003
|
return superLocal;
|
|
9714
10004
|
}
|
|
9715
10005
|
}
|
|
@@ -9726,7 +10016,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9726
10016
|
let parent: Element | null = ctxFlow.sourceFunction.parent;
|
|
9727
10017
|
if (parent && parent.kind == ElementKind.Class) {
|
|
9728
10018
|
let base = (<Class>parent).base;
|
|
9729
|
-
@@ -2351,6 +
|
|
10019
|
+
@@ -2351,6 +2697,12 @@ export class Resolver extends DiagnosticEmitter {
|
|
9730
10020
|
return this.program.regexpInstance;
|
|
9731
10021
|
}
|
|
9732
10022
|
case LiteralKind.Array: {
|
|
@@ -9739,7 +10029,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9739
10029
|
let classReference = ctxType.getClass();
|
|
9740
10030
|
if (classReference && classReference.prototype == this.program.arrayPrototype) {
|
|
9741
10031
|
return this.getElementOfType(ctxType);
|
|
9742
|
-
@@ -2400,6 +
|
|
10032
|
+
@@ -2400,6 +2752,13 @@ export class Resolver extends DiagnosticEmitter {
|
|
9743
10033
|
}
|
|
9744
10034
|
case LiteralKind.Object: {
|
|
9745
10035
|
if (ctxType.isClass) return ctxType.classReference;
|
|
@@ -9753,7 +10043,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9753
10043
|
if (reportMode == ReportMode.Report) {
|
|
9754
10044
|
this.error(
|
|
9755
10045
|
DiagnosticCode.Expression_cannot_be_represented_by_a_type,
|
|
9756
|
-
@@ -2474,6 +
|
|
10046
|
+
@@ -2474,6 +2833,24 @@ export class Resolver extends DiagnosticEmitter {
|
|
9757
10047
|
/** How to proceed with eventual diagnostics. */
|
|
9758
10048
|
reportMode: ReportMode = ReportMode.Report
|
|
9759
10049
|
): Type | null {
|
|
@@ -9778,7 +10068,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9778
10068
|
let targetExpression = node.expression;
|
|
9779
10069
|
let target = this.lookupExpression( // reports
|
|
9780
10070
|
targetExpression,
|
|
9781
|
-
@@ -2623,6 +
|
|
10071
|
+
@@ -2623,6 +3000,12 @@ export class Resolver extends DiagnosticEmitter {
|
|
9782
10072
|
/** How to proceed with eventual diagnostics. */
|
|
9783
10073
|
reportMode: ReportMode = ReportMode.Report
|
|
9784
10074
|
): Type | null {
|
|
@@ -9791,7 +10081,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9791
10081
|
let thenType = this.resolveExpression(node.ifThen, ctxFlow, ctxType, reportMode);
|
|
9792
10082
|
if (!thenType) return null;
|
|
9793
10083
|
let elseType = this.resolveExpression(node.ifElse, ctxFlow, thenType, reportMode);
|
|
9794
|
-
@@ -2736,18 +
|
|
10084
|
+
@@ -2736,18 +3119,129 @@ export class Resolver extends DiagnosticEmitter {
|
|
9795
10085
|
const declaration = node.declaration;
|
|
9796
10086
|
const signature = declaration.signature;
|
|
9797
10087
|
const body = declaration.body;
|
|
@@ -9839,23 +10129,33 @@ index 9576a47..d1fd13d 100644
|
|
|
9839
10129
|
+ // its untyped parameters from that type, as TypeScript's contextual typing
|
|
9840
10130
|
+ // does - which is how game.addEventListener("x", (event) => answer) learns
|
|
9841
10131
|
+ // what the listener returns, and from it the generic R.
|
|
10132
|
+
+ // amxts: and an arrow's return type left out is read off its body below,
|
|
10133
|
+
+ // `[() => log(1)]` too - no error for it here, where it is void until then.
|
|
9842
10134
|
+ let ctxSignature = ctxType.getSignature();
|
|
9843
10135
|
+ let untyped = false;
|
|
9844
10136
|
+ for (let i = 0, k = signature.parameters.length; i < k; ++i) {
|
|
9845
10137
|
+ if (isTypeOmitted(signature.parameters[i].type)) untyped = true;
|
|
9846
10138
|
+ }
|
|
10139
|
+
+ let returnInferred = declaration.arrowKind != ArrowKind.None && isTypeOmitted(signature.returnType);
|
|
9847
10140
|
+ let functionType: Type | null = null;
|
|
9848
|
-
+ if (
|
|
10141
|
+
+ if (
|
|
10142
|
+
+ untyped ? ctxSignature != null && ctxSignature.parameterTypes.length >= signature.parameters.length : returnInferred
|
|
10143
|
+
+ ) {
|
|
9849
10144
|
+ let parameterTypes = new Array<Type>(signature.parameters.length);
|
|
10145
|
+
+ let requiredParameters = 0;
|
|
10146
|
+
+ let hasRest = false;
|
|
9850
10147
|
+ for (let i = 0, k = signature.parameters.length; i < k; ++i) {
|
|
9851
|
-
+ let
|
|
10148
|
+
+ let parameter = signature.parameters[i];
|
|
10149
|
+
+ if (parameter.parameterKind == ParameterKind.Default) requiredParameters = i + 1;
|
|
10150
|
+
+ else if (parameter.parameterKind == ParameterKind.Rest) hasRest = true;
|
|
10151
|
+
+ let typeNode = parameter.type;
|
|
9852
10152
|
+ let type = isTypeOmitted(typeNode)
|
|
9853
|
-
+ ? ctxSignature
|
|
10153
|
+
+ ? ctxSignature!.parameterTypes[i]
|
|
9854
10154
|
+ : this.resolveType(typeNode, null, ctxFlow.sourceFunction, ctxFlow.contextualTypeArguments, reportMode);
|
|
9855
10155
|
+ if (!type) return null;
|
|
9856
10156
|
+ parameterTypes[i] = type;
|
|
9857
10157
|
+ }
|
|
9858
|
-
+ functionType = Signature.create(this.program, parameterTypes, Type.void, null,
|
|
10158
|
+
+ functionType = Signature.create(this.program, parameterTypes, Type.void, null, requiredParameters, hasRest).type;
|
|
9859
10159
|
+ } else {
|
|
9860
10160
|
+ functionType = this.resolveType(signature, null, ctxFlow.sourceFunction, ctxFlow.contextualTypeArguments, reportMode);
|
|
9861
10161
|
+ }
|
|
@@ -9914,7 +10214,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9914
10214
|
let parameters = signature.parameters;
|
|
9915
10215
|
// return type of resolveFunctionType should have same parameter length with signature
|
|
9916
10216
|
assert(signatureReference.parameterTypes.length == parameters.length);
|
|
9917
|
-
@@ -2756,16 +
|
|
10217
|
+
@@ -2756,16 +3250,57 @@ export class Resolver extends DiagnosticEmitter {
|
|
9918
10218
|
const type = signatureReference.parameterTypes[i];
|
|
9919
10219
|
tempFlow.addScopedDummyLocal(parameter.name.text, type, parameter);
|
|
9920
10220
|
}
|
|
@@ -9975,7 +10275,7 @@ index 9576a47..d1fd13d 100644
|
|
|
9975
10275
|
}
|
|
9976
10276
|
}
|
|
9977
10277
|
return functionType;
|
|
9978
|
-
@@ -2870,13 +
|
|
10278
|
+
@@ -2870,13 +3405,17 @@ export class Resolver extends DiagnosticEmitter {
|
|
9979
10279
|
}
|
|
9980
10280
|
return null;
|
|
9981
10281
|
}
|
|
@@ -10000,7 +10300,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10000
10300
|
if (!parameterType) return null;
|
|
10001
10301
|
if (parameterType == Type.void) {
|
|
10002
10302
|
if (reportMode == ReportMode.Report) {
|
|
10003
|
-
@@ -2891,14 +
|
|
10303
|
+
@@ -2891,14 +3430,73 @@ export class Resolver extends DiagnosticEmitter {
|
|
10004
10304
|
}
|
|
10005
10305
|
|
|
10006
10306
|
// resolve return type
|
|
@@ -10076,7 +10376,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10076
10376
|
if (reportMode == ReportMode.Report) {
|
|
10077
10377
|
this.error(
|
|
10078
10378
|
DiagnosticCode.Type_expected,
|
|
10079
|
-
@@ -2906,7 +
|
|
10379
|
+
@@ -2906,7 +3504,7 @@ export class Resolver extends DiagnosticEmitter {
|
|
10080
10380
|
);
|
|
10081
10381
|
}
|
|
10082
10382
|
return null;
|
|
@@ -10085,7 +10385,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10085
10385
|
let type = this.resolveType(
|
|
10086
10386
|
typeNode,
|
|
10087
10387
|
null,
|
|
10088
|
-
@@ -2916,6 +
|
|
10388
|
+
@@ -2916,6 +3514,7 @@ export class Resolver extends DiagnosticEmitter {
|
|
10089
10389
|
);
|
|
10090
10390
|
if (!type) return null;
|
|
10091
10391
|
returnType = type;
|
|
@@ -10093,7 +10393,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10093
10393
|
}
|
|
10094
10394
|
|
|
10095
10395
|
let signature = Signature.create(this.program, parameterTypes, returnType, thisType, requiredParameters, hasRest);
|
|
10096
|
-
@@ -3041,7 +
|
|
10396
|
+
@@ -3041,7 +3640,8 @@ export class Resolver extends DiagnosticEmitter {
|
|
10097
10397
|
ctxElement,
|
|
10098
10398
|
ctxTypes, // update
|
|
10099
10399
|
reportNode,
|
|
@@ -10103,7 +10403,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10103
10403
|
);
|
|
10104
10404
|
if (!resolvedTypeArguments) return null;
|
|
10105
10405
|
|
|
10106
|
-
@@ -3089,7 +
|
|
10406
|
+
@@ -3089,7 +3689,7 @@ export class Resolver extends DiagnosticEmitter {
|
|
10107
10407
|
for (let _values = Map_values(classInstances), j = 0, l = _values.length; j < l; ++j) {
|
|
10108
10408
|
let classInstance = _values[j];
|
|
10109
10409
|
// Check if the parent class is a subtype of instance's class
|
|
@@ -10112,7 +10412,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10112
10412
|
let overrideInstance: Function | null = null;
|
|
10113
10413
|
if (instance.isAny(CommonFlags.Get | CommonFlags.Set)) {
|
|
10114
10414
|
let propertyName = instance.declaration.name.text;
|
|
10115
|
-
@@ -3125,6 +
|
|
10415
|
+
@@ -3125,6 +3725,21 @@ export class Resolver extends DiagnosticEmitter {
|
|
10116
10416
|
return Set_values(overrides);
|
|
10117
10417
|
}
|
|
10118
10418
|
|
|
@@ -10134,7 +10434,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10134
10434
|
/** Currently resolving classes. */
|
|
10135
10435
|
private resolveClassPending: Set<Class> = new Set();
|
|
10136
10436
|
|
|
10137
|
-
@@ -3139,6 +
|
|
10437
|
+
@@ -3139,6 +3754,13 @@ export class Resolver extends DiagnosticEmitter {
|
|
10138
10438
|
/** How to proceed with eventual diagnostics. */
|
|
10139
10439
|
reportMode: ReportMode = ReportMode.Report
|
|
10140
10440
|
): Class | null {
|
|
@@ -10148,7 +10448,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10148
10448
|
let instanceKey = typeArguments ? typesToString(typeArguments) : "";
|
|
10149
10449
|
|
|
10150
10450
|
// Do not attempt to resolve the same class twice. This can return a class
|
|
10151
|
-
@@ -3416,6 +
|
|
10451
|
+
@@ -3416,6 +4038,10 @@ export class Resolver extends DiagnosticEmitter {
|
|
10152
10452
|
}
|
|
10153
10453
|
|
|
10154
10454
|
// Resolve instance members
|
|
@@ -10159,7 +10459,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10159
10459
|
let prototype = instance.prototype;
|
|
10160
10460
|
let instanceMemberPrototypes = prototype.instanceMembers;
|
|
10161
10461
|
if (instanceMemberPrototypes) {
|
|
10162
|
-
@@ -3465,18 +
|
|
10462
|
+
@@ -3465,18 +4091,12 @@ export class Resolver extends DiagnosticEmitter {
|
|
10163
10463
|
break; // keep existing
|
|
10164
10464
|
}
|
|
10165
10465
|
boundInstance.memoryOffset = existingProperty.memoryOffset;
|
|
@@ -10180,7 +10480,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10180
10480
|
boundPrototype.instance = boundInstance;
|
|
10181
10481
|
instance.add(boundPrototype.name, boundPrototype); // reports
|
|
10182
10482
|
// field materializes here, so check for supported type early
|
|
10183
|
-
@@ -3500,6 +
|
|
10483
|
+
@@ -3500,6 +4120,31 @@ export class Resolver extends DiagnosticEmitter {
|
|
10184
10484
|
}
|
|
10185
10485
|
}
|
|
10186
10486
|
|
|
@@ -10212,7 +10512,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10212
10512
|
if (instance.kind != ElementKind.Interface) {
|
|
10213
10513
|
|
|
10214
10514
|
// Check that all required members are implemented
|
|
10215
|
-
@@ -3675,7 +
|
|
10515
|
+
@@ -3675,7 +4320,8 @@ export class Resolver extends DiagnosticEmitter {
|
|
10216
10516
|
ctxElement,
|
|
10217
10517
|
ctxTypes, // update
|
|
10218
10518
|
reportNode,
|
|
@@ -10222,7 +10522,7 @@ index 9576a47..d1fd13d 100644
|
|
|
10222
10522
|
);
|
|
10223
10523
|
}
|
|
10224
10524
|
|
|
10225
|
-
@@ -3749,6 +
|
|
10525
|
+
@@ -3749,6 +4395,1009 @@ export class Resolver extends DiagnosticEmitter {
|
|
10226
10526
|
return instance;
|
|
10227
10527
|
}
|
|
10228
10528
|
|
|
@@ -11176,7 +11476,7 @@ index 9576a47..d1fd13d 100644
|
|
|
11176
11476
|
+ let callee = (<CallExpression>value).expression;
|
|
11177
11477
|
+ if (callee.kind == NodeKind.Identifier && (<IdentifierExpression>callee).text == prototype.name) continue;
|
|
11178
11478
|
+ }
|
|
11179
|
-
+ // `if (player == null) return
|
|
11479
|
+
+ // `if (player == null) return server.players; return [player];` - an
|
|
11180
11480
|
+ // array literal after another return takes that return's type, as its
|
|
11181
11481
|
+ // elements would in TypeScript once narrowed; the body's own compile
|
|
11182
11482
|
+ // still checks each element against it.
|
|
@@ -11232,7 +11532,7 @@ index 9576a47..d1fd13d 100644
|
|
|
11232
11532
|
ensureOneTypeArgument(
|
|
11233
11533
|
/** The type to resolve. */
|
|
11234
11534
|
node: NamedTypeNode,
|
|
11235
|
-
@@ -3769,3 +
|
|
11535
|
+
@@ -3769,3 +5418,55 @@ export class Resolver extends DiagnosticEmitter {
|
|
11236
11536
|
return typeArgumentNodes[0];
|
|
11237
11537
|
}
|
|
11238
11538
|
}
|
|
@@ -11525,6 +11825,54 @@ index 85c59ff..203868e 100644
|
|
|
11525
11825
|
}
|
|
11526
11826
|
|
|
11527
11827
|
export declare namespace console {
|
|
11828
|
+
diff --git a/std/assembly/console.ts b/std/assembly/console.ts
|
|
11829
|
+
index 26a18a4..73426b9 100644
|
|
11830
|
+
--- a/std/assembly/console.ts
|
|
11831
|
+
+++ b/std/assembly/console.ts
|
|
11832
|
+
@@ -8,24 +8,33 @@ export namespace console {
|
|
11833
|
+
binding.assert(!!condition, message);
|
|
11834
|
+
}
|
|
11835
|
+
|
|
11836
|
+
- export function log(message: string = ""): void {
|
|
11837
|
+
- binding.log(message);
|
|
11838
|
+
+ // amxts: a string, or an Error - written as its stack, as JavaScript's console does
|
|
11839
|
+
+ export function log<T = string>(message: T = changetype<T>("")): void {
|
|
11840
|
+
+ binding.log(text<T>(message));
|
|
11841
|
+
}
|
|
11842
|
+
|
|
11843
|
+
- export function debug(message: string = ""): void {
|
|
11844
|
+
- binding.debug(message);
|
|
11845
|
+
+ export function debug<T = string>(message: T = changetype<T>("")): void {
|
|
11846
|
+
+ binding.debug(text<T>(message));
|
|
11847
|
+
}
|
|
11848
|
+
|
|
11849
|
+
- export function info(message: string = ""): void {
|
|
11850
|
+
- binding.info(message);
|
|
11851
|
+
+ export function info<T = string>(message: T = changetype<T>("")): void {
|
|
11852
|
+
+ binding.info(text<T>(message));
|
|
11853
|
+
}
|
|
11854
|
+
|
|
11855
|
+
- export function warn(message: string = ""): void {
|
|
11856
|
+
- binding.warn(message);
|
|
11857
|
+
+ export function warn<T = string>(message: T = changetype<T>("")): void {
|
|
11858
|
+
+ binding.warn(text<T>(message));
|
|
11859
|
+
}
|
|
11860
|
+
|
|
11861
|
+
- export function error(message: string = ""): void {
|
|
11862
|
+
- binding.error(message);
|
|
11863
|
+
+ export function error<T = string>(message: T = changetype<T>("")): void {
|
|
11864
|
+
+ binding.error(text<T>(message));
|
|
11865
|
+
+ }
|
|
11866
|
+
+
|
|
11867
|
+
+ // @ts-ignore: decorator
|
|
11868
|
+
+ @inline function text<T>(message: T): string {
|
|
11869
|
+
+ if (isString<T>()) return changetype<string>(message);
|
|
11870
|
+
+ if (isReference<T>() && !isNullable<T>() && message instanceof Error) return changetype<Error>(message).stack;
|
|
11871
|
+
+ ERROR("console takes a string or an Error");
|
|
11872
|
+
+ return "";
|
|
11873
|
+
}
|
|
11874
|
+
|
|
11875
|
+
export function time(label: string = "default"): void {
|
|
11528
11876
|
diff --git a/std/assembly/date.ts b/std/assembly/date.ts
|
|
11529
11877
|
index 7d273e1..abdb34d 100644
|
|
11530
11878
|
--- a/std/assembly/date.ts
|
|
@@ -11787,10 +12135,60 @@ index 7d273e1..abdb34d 100644
|
|
|
11787
12135
|
+ return LOCALE_GB;
|
|
11788
12136
|
+}
|
|
11789
12137
|
diff --git a/std/assembly/error.ts b/std/assembly/error.ts
|
|
11790
|
-
index f4ea058..
|
|
12138
|
+
index f4ea058..a52176c 100644
|
|
11791
12139
|
--- a/std/assembly/error.ts
|
|
11792
12140
|
+++ b/std/assembly/error.ts
|
|
11793
|
-
@@ -
|
|
12141
|
+
@@ -1,12 +1,24 @@
|
|
12142
|
+
export class Error {
|
|
12143
|
+
|
|
12144
|
+
name: string = "Error";
|
|
12145
|
+
- stack: string = ""; // TODO
|
|
12146
|
+
+
|
|
12147
|
+
+ // amxts: the calls that made it, as the host keeps them, for `stack`
|
|
12148
|
+
+ /** @hidden */
|
|
12149
|
+
+ __frames: StaticArray<u32> | null = __errorStack ? changetype<ErrorStack>(__errorStack).frames() : null;
|
|
12150
|
+
|
|
12151
|
+
constructor(
|
|
12152
|
+
public message: string = ""
|
|
12153
|
+
) {}
|
|
12154
|
+
|
|
12155
|
+
+ /** amxts: the error and where it was made, a call a line, as JavaScript writes it. */
|
|
12156
|
+
+ get stack(): string {
|
|
12157
|
+
+ let hook = __errorStack;
|
|
12158
|
+
+ let frames = this.__frames;
|
|
12159
|
+
+ if (!hook || !frames) return this.toString();
|
|
12160
|
+
+ let calls = hook.text(frames);
|
|
12161
|
+
+ return calls.length ? this.toString() + "\n" + calls : this.toString();
|
|
12162
|
+
+ }
|
|
12163
|
+
+
|
|
12164
|
+
toString(): string {
|
|
12165
|
+
let message = this.message;
|
|
12166
|
+
return message.length
|
|
12167
|
+
@@ -15,6 +27,23 @@ export class Error {
|
|
12168
|
+
}
|
|
12169
|
+
}
|
|
12170
|
+
|
|
12171
|
+
+/**
|
|
12172
|
+
+ * @hidden amxts: what an error's `stack` is made of - the frames of the calls
|
|
12173
|
+
+ * that made it, then their words - which only the host the plugin runs on
|
|
12174
|
+
+ * has. The hood sets it (as/facade.ts); without it `stack` is the error's
|
|
12175
|
+
+ * first line alone.
|
|
12176
|
+
+ */
|
|
12177
|
+
+export abstract class ErrorStack {
|
|
12178
|
+
+ /** The frames of the calls running now. */
|
|
12179
|
+
+ abstract frames(): StaticArray<u32>;
|
|
12180
|
+
+ /** `frames` as lines: " at name (file:line:column)". */
|
|
12181
|
+
+ abstract text(frames: StaticArray<u32>): string;
|
|
12182
|
+
+}
|
|
12183
|
+
+
|
|
12184
|
+
+/** @hidden see ErrorStack. */
|
|
12185
|
+
+// @ts-ignore: decorator
|
|
12186
|
+
+@lazy export let __errorStack: ErrorStack | null = null;
|
|
12187
|
+
+
|
|
12188
|
+
export class RangeError extends Error {
|
|
12189
|
+
constructor(message: string = "") {
|
|
12190
|
+
super(message);
|
|
12191
|
+
@@ -29,6 +58,14 @@ export class TypeError extends Error {
|
|
11794
12192
|
}
|
|
11795
12193
|
}
|
|
11796
12194
|
|
|
@@ -11805,7 +12203,7 @@ index f4ea058..5f6e74c 100644
|
|
|
11805
12203
|
export class SyntaxError extends Error {
|
|
11806
12204
|
constructor(message: string = "") {
|
|
11807
12205
|
super(message);
|
|
11808
|
-
@@ -42,3 +
|
|
12206
|
+
@@ -42,3 +79,34 @@ export class URIError extends Error {
|
|
11809
12207
|
this.name = "URIError";
|
|
11810
12208
|
}
|
|
11811
12209
|
}
|
|
@@ -11830,7 +12228,7 @@ index f4ea058..5f6e74c 100644
|
|
|
11830
12228
|
+ __thrown = error;
|
|
11831
12229
|
+ return true;
|
|
11832
12230
|
+ }
|
|
11833
|
-
+ abort(error.
|
|
12231
|
+
+ abort(error.toString(), fileName, lineNumber, columnNumber);
|
|
11834
12232
|
+ return false;
|
|
11835
12233
|
+}
|
|
11836
12234
|
+
|
|
@@ -11841,7 +12239,7 @@ index f4ea058..5f6e74c 100644
|
|
|
11841
12239
|
+ return error;
|
|
11842
12240
|
+}
|
|
11843
12241
|
diff --git a/std/assembly/function.ts b/std/assembly/function.ts
|
|
11844
|
-
index dd32696..
|
|
12242
|
+
index dd32696..5e6d083 100644
|
|
11845
12243
|
--- a/std/assembly/function.ts
|
|
11846
12244
|
+++ b/std/assembly/function.ts
|
|
11847
12245
|
@@ -6,6 +6,11 @@ type auto = i32;
|
|
@@ -11856,7 +12254,7 @@ index dd32696..5087e0d 100644
|
|
|
11856
12254
|
return load<u32>(changetype<usize>(this), offsetof<Function<T>>("_index"));
|
|
11857
12255
|
}
|
|
11858
12256
|
|
|
11859
|
-
@@ -36,3 +41,
|
|
12257
|
+
@@ -36,3 +41,125 @@ type auto = i32;
|
|
11860
12258
|
__visit(this._env, cookie);
|
|
11861
12259
|
}
|
|
11862
12260
|
}
|
|
@@ -11972,6 +12370,16 @@ index dd32696..5087e0d 100644
|
|
|
11972
12370
|
+ const fn: F = () => text;
|
|
11973
12371
|
+ return fn;
|
|
11974
12372
|
+}
|
|
12373
|
+
+
|
|
12374
|
+
+/**
|
|
12375
|
+
+ * amxts: a boolean given where `boolean | (...) => boolean` is declared - held
|
|
12376
|
+
+ * as the function, so a boolean becomes one that returns it
|
|
12377
|
+
+ * (Compiler.compileText).
|
|
12378
|
+
+ */
|
|
12379
|
+
+export function __boolFunction<F>(value: bool): F {
|
|
12380
|
+
+ const fn: F = () => value;
|
|
12381
|
+
+ return fn;
|
|
12382
|
+
+}
|
|
11975
12383
|
diff --git a/std/assembly/index.d.ts b/std/assembly/index.d.ts
|
|
11976
12384
|
index a604397..dd80104 100644
|
|
11977
12385
|
--- a/std/assembly/index.d.ts
|
|
@@ -12530,7 +12938,7 @@ index 0000000..7eaa4f6
|
|
|
12530
12938
|
+ }
|
|
12531
12939
|
+}
|
|
12532
12940
|
diff --git a/std/assembly/map.ts b/std/assembly/map.ts
|
|
12533
|
-
index ab7302f..
|
|
12941
|
+
index ab7302f..3f17444 100644
|
|
12534
12942
|
--- a/std/assembly/map.ts
|
|
12535
12943
|
+++ b/std/assembly/map.ts
|
|
12536
12944
|
@@ -2,6 +2,7 @@
|
|
@@ -12541,7 +12949,7 @@ index ab7302f..7e96401 100644
|
|
|
12541
12949
|
|
|
12542
12950
|
// A deterministic hash map based on CloseTable from https://github.com/jorendorff/dht
|
|
12543
12951
|
|
|
12544
|
-
@@ -61,
|
|
12952
|
+
@@ -61,13 +62,19 @@ export class Map<K,V> {
|
|
12545
12953
|
private bucketsMask: u32 = INITIAL_CAPACITY - 1;
|
|
12546
12954
|
|
|
12547
12955
|
// entries in insertion order, MapEntry<K,V>[entriesCapacity]
|
|
@@ -12550,7 +12958,21 @@ index ab7302f..7e96401 100644
|
|
|
12550
12958
|
private entriesCapacity: i32 = INITIAL_CAPACITY;
|
|
12551
12959
|
private entriesOffset: i32 = 0;
|
|
12552
12960
|
private entriesCount: i32 = 0;
|
|
12553
|
-
|
|
12961
|
+
|
|
12962
|
+
- constructor() {
|
|
12963
|
+
- /* nop */
|
|
12964
|
+
+ /** amxts: `new Map(entries)` sets the `[key, value]` entries in their order, as JavaScript's Map does. */
|
|
12965
|
+
+ constructor(entries: __Tuple2<K,V>[] | null = null) {
|
|
12966
|
+
+ if (entries) {
|
|
12967
|
+
+ for (let i = 0, k = entries.length; i < k; ++i) {
|
|
12968
|
+
+ let entry = unchecked(entries[i]);
|
|
12969
|
+
+ this.set(entry._0, entry._1);
|
|
12970
|
+
+ }
|
|
12971
|
+
+ }
|
|
12972
|
+
}
|
|
12973
|
+
|
|
12974
|
+
get size(): i32 {
|
|
12975
|
+
@@ -77,7 +84,7 @@ export class Map<K,V> {
|
|
12554
12976
|
clear(): void {
|
|
12555
12977
|
this.buckets = new ArrayBuffer(INITIAL_CAPACITY * <i32>BUCKET_SIZE);
|
|
12556
12978
|
this.bucketsMask = INITIAL_CAPACITY - 1;
|
|
@@ -12559,7 +12981,7 @@ index ab7302f..7e96401 100644
|
|
|
12559
12981
|
this.entriesCapacity = INITIAL_CAPACITY;
|
|
12560
12982
|
this.entriesOffset = 0;
|
|
12561
12983
|
this.entriesCount = 0;
|
|
12562
|
-
@@ -106,6 +
|
|
12984
|
+
@@ -106,6 +113,17 @@ export class Map<K,V> {
|
|
12563
12985
|
return entry.value;
|
|
12564
12986
|
}
|
|
12565
12987
|
|
|
@@ -12577,7 +12999,7 @@ index ab7302f..7e96401 100644
|
|
|
12577
12999
|
@operator("[]=")
|
|
12578
13000
|
set(key: K, value: V): this {
|
|
12579
13001
|
let hashCode = HASH<K>(key);
|
|
12580
|
-
@@ -125,7 +
|
|
13002
|
+
@@ -125,7 +143,7 @@ export class Map<K,V> {
|
|
12581
13003
|
);
|
|
12582
13004
|
}
|
|
12583
13005
|
// append new entry
|
|
@@ -12586,7 +13008,7 @@ index ab7302f..7e96401 100644
|
|
|
12586
13008
|
entry = changetype<MapEntry<K,V>>(changetype<usize>(entries) + <usize>(this.entriesOffset++) * ENTRY_SIZE<K,V>());
|
|
12587
13009
|
// link with the map
|
|
12588
13010
|
entry.key = key;
|
|
12589
|
-
@@ -166,7 +
|
|
13011
|
+
@@ -166,7 +184,7 @@ export class Map<K,V> {
|
|
12590
13012
|
let newEntries = new ArrayBuffer(newEntriesCapacity * <i32>ENTRY_SIZE<K,V>());
|
|
12591
13013
|
|
|
12592
13014
|
// copy old entries to new entries
|
|
@@ -12595,7 +13017,7 @@ index ab7302f..7e96401 100644
|
|
|
12595
13017
|
let oldEnd = oldPtr + <usize>this.entriesOffset * ENTRY_SIZE<K,V>();
|
|
12596
13018
|
let newPtr = changetype<usize>(newEntries);
|
|
12597
13019
|
while (oldPtr != oldEnd) {
|
|
12598
|
-
@@ -187,14 +
|
|
13020
|
+
@@ -187,14 +205,14 @@ export class Map<K,V> {
|
|
12599
13021
|
|
|
12600
13022
|
this.buckets = newBuckets;
|
|
12601
13023
|
this.bucketsMask = newBucketsMask;
|
|
@@ -12612,7 +13034,7 @@ index ab7302f..7e96401 100644
|
|
|
12612
13034
|
let size = this.entriesOffset;
|
|
12613
13035
|
let keys = new Array<K>(size);
|
|
12614
13036
|
let length = 0;
|
|
12615
|
-
@@ -210,7 +
|
|
13037
|
+
@@ -210,7 +228,7 @@ export class Map<K,V> {
|
|
12616
13038
|
|
|
12617
13039
|
values(): V[] {
|
|
12618
13040
|
// FIXME: this is preliminary, needs iterators/closures
|
|
@@ -12621,7 +13043,7 @@ index ab7302f..7e96401 100644
|
|
|
12621
13043
|
let size = this.entriesOffset;
|
|
12622
13044
|
let values = new Array<V>(size);
|
|
12623
13045
|
let length = 0;
|
|
12624
|
-
@@ -224,6 +
|
|
13046
|
+
@@ -224,6 +242,29 @@ export class Map<K,V> {
|
|
12625
13047
|
return values;
|
|
12626
13048
|
}
|
|
12627
13049
|
|
|
@@ -12651,7 +13073,7 @@ index ab7302f..7e96401 100644
|
|
|
12651
13073
|
toString(): string {
|
|
12652
13074
|
return "[object Map]";
|
|
12653
13075
|
}
|
|
12654
|
-
@@ -232,7 +
|
|
13076
|
+
@@ -232,7 +273,7 @@ export class Map<K,V> {
|
|
12655
13077
|
|
|
12656
13078
|
@unsafe private __visit(cookie: u32): void {
|
|
12657
13079
|
__visit(changetype<usize>(this.buckets), cookie);
|
|
@@ -12660,7 +13082,7 @@ index ab7302f..7e96401 100644
|
|
|
12660
13082
|
if (isManaged<K>() || isManaged<V>()) {
|
|
12661
13083
|
let cur = entries;
|
|
12662
13084
|
let end = cur + <usize>this.entriesOffset * ENTRY_SIZE<K,V>();
|
|
12663
|
-
@@ -258,3 +
|
|
13085
|
+
@@ -258,3 +299,92 @@ export class Map<K,V> {
|
|
12664
13086
|
__visit(entries, cookie);
|
|
12665
13087
|
}
|
|
12666
13088
|
}
|
|
@@ -12754,10 +13176,30 @@ index ab7302f..7e96401 100644
|
|
|
12754
13176
|
+ }
|
|
12755
13177
|
+}
|
|
12756
13178
|
diff --git a/std/assembly/math.ts b/std/assembly/math.ts
|
|
12757
|
-
index e93837b..
|
|
13179
|
+
index e93837b..bdf5633 100644
|
|
12758
13180
|
--- a/std/assembly/math.ts
|
|
12759
13181
|
+++ b/std/assembly/math.ts
|
|
12760
|
-
@@ -
|
|
13182
|
+
@@ -1592,6 +1592,19 @@ export namespace NativeMath {
|
|
13183
|
+
}
|
|
13184
|
+
|
|
13185
|
+
export function mod(x: f64, y: f64): f64 { // see: musl/src/math/fmod.c
|
|
13186
|
+
+ // amxts: a plugin's whole numbers are f64, and `n % d` of two of them
|
|
13187
|
+
+ // within i32 is i32's remainder, which takes the dividend's sign as
|
|
13188
|
+
+ // JavaScript's does; a zero keeps the dividend's sign (-4 % 2 is -0).
|
|
13189
|
+
+ // NaN, infinities, fractions, a zero divisor and larger numbers go on
|
|
13190
|
+
+ // to the general remainder below.
|
|
13191
|
+
+ if (builtin_abs<f64>(x) < 2147483648.0 && builtin_abs<f64>(y) < 2147483648.0) {
|
|
13192
|
+
+ let ix = <i32>x;
|
|
13193
|
+
+ let iy = <i32>y;
|
|
13194
|
+
+ if (<f64>ix == x && <f64>iy == y && iy != 0) {
|
|
13195
|
+
+ let r = ix % iy;
|
|
13196
|
+
+ return r ? <f64>r : builtin_copysign<f64>(0.0, x);
|
|
13197
|
+
+ }
|
|
13198
|
+
+ }
|
|
13199
|
+
if (builtin_abs<f64>(y) == 1.0) {
|
|
13200
|
+
// x % 1, x % -1 ==> sign(x) * abs(x - 1.0 * trunc(x / 1.0))
|
|
13201
|
+
// TODO: move this rule to compiler's optimization pass.
|
|
13202
|
+
@@ -3287,3 +3300,25 @@ switch (e) {
|
|
12761
13203
|
case 63:
|
|
12762
13204
|
}
|
|
12763
13205
|
*/
|
|
@@ -13981,10 +14423,24 @@ index 8ed6063..efa6398 100644
|
|
|
13981
14423
|
+ return c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c == 0x5F || c >= 0x61 && c <= 0x7A;
|
|
13982
14424
|
}
|
|
13983
14425
|
diff --git a/std/assembly/set.ts b/std/assembly/set.ts
|
|
13984
|
-
index ca2d6e4..
|
|
14426
|
+
index ca2d6e4..b8959cf 100644
|
|
13985
14427
|
--- a/std/assembly/set.ts
|
|
13986
14428
|
+++ b/std/assembly/set.ts
|
|
13987
|
-
@@ -
|
|
14429
|
+
@@ -63,8 +63,11 @@ export class Set<T> {
|
|
14430
|
+
private entriesOffset: i32 = 0;
|
|
14431
|
+
private entriesCount: i32 = 0;
|
|
14432
|
+
|
|
14433
|
+
- constructor() {
|
|
14434
|
+
- /* nop */
|
|
14435
|
+
+ /** amxts: `new Set(values)` adds the values in their order, as JavaScript's Set does. */
|
|
14436
|
+
+ constructor(values: T[] | null = null) {
|
|
14437
|
+
+ if (values) {
|
|
14438
|
+
+ for (let i = 0, k = values.length; i < k; ++i) this.add(unchecked(values[i]));
|
|
14439
|
+
+ }
|
|
14440
|
+
}
|
|
14441
|
+
|
|
14442
|
+
get size(): i32 {
|
|
14443
|
+
@@ -192,6 +195,12 @@ export class Set<T> {
|
|
13988
14444
|
return values;
|
|
13989
14445
|
}
|
|
13990
14446
|
|