@grey-ts/transpiler 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +238 -211
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -486,7 +486,7 @@ end function`;
|
|
|
486
486
|
});
|
|
487
487
|
|
|
488
488
|
// src/visitors/expressions.ts
|
|
489
|
-
import
|
|
489
|
+
import ts8 from "typescript";
|
|
490
490
|
|
|
491
491
|
// src/call_transformers/callTransformer.ts
|
|
492
492
|
import path2 from "node:path";
|
|
@@ -548,12 +548,136 @@ CallTransformer.register("String", (name, args) => {
|
|
|
548
548
|
return `str(${args[0]})`;
|
|
549
549
|
});
|
|
550
550
|
|
|
551
|
+
// src/visitors/objects.ts
|
|
552
|
+
import ts7 from "typescript";
|
|
553
|
+
var assignmentOperators = new Set([
|
|
554
|
+
"=",
|
|
555
|
+
"??=",
|
|
556
|
+
"||=",
|
|
557
|
+
"-=",
|
|
558
|
+
"+="
|
|
559
|
+
]);
|
|
560
|
+
function valueIsBeingAssignedToNode(node) {
|
|
561
|
+
const assignAncestor = ts7.findAncestor(node, (ancestor) => {
|
|
562
|
+
if (ancestor.parent && ts7.isBinaryExpression(ancestor.parent) && ancestor === ancestor.parent.left) {
|
|
563
|
+
const token = ts7.tokenToString(ancestor.parent.operatorToken.kind) || ancestor.parent.operatorToken.getText();
|
|
564
|
+
return assignmentOperators.has(token);
|
|
565
|
+
}
|
|
566
|
+
return false;
|
|
567
|
+
});
|
|
568
|
+
return !!assignAncestor;
|
|
569
|
+
}
|
|
570
|
+
NodeHandler.register(ts7.SyntaxKind.PropertyAccessExpression, (node, ctx) => {
|
|
571
|
+
const left = NodeHandler.handle(node.expression);
|
|
572
|
+
let right = NodeHandler.handle(node.name);
|
|
573
|
+
right = replaceIdentifier(right, checker.getTypeAtLocation(node.expression), right);
|
|
574
|
+
const nodeSymbol = checker.getSymbolAtLocation(node);
|
|
575
|
+
if (ctx.namespaceImports[ctx.currentFilePath]?.has(left))
|
|
576
|
+
return right;
|
|
577
|
+
let getSafely = !!node.questionDotToken && !ts7.isNonNullExpression(node.parent);
|
|
578
|
+
const rightType = checker.getTypeAtLocation(node.name);
|
|
579
|
+
if (rightType.isUnion()) {
|
|
580
|
+
const hasUndefined = rightType.types.some((t) => t.flags === ts7.TypeFlags.Undefined);
|
|
581
|
+
if (hasUndefined)
|
|
582
|
+
getSafely = true;
|
|
583
|
+
}
|
|
584
|
+
if (!valueIsBeingAssignedToNode(node) && getSafely)
|
|
585
|
+
return callUtilFunction("get_property", left, `"${right}"`);
|
|
586
|
+
let output = `${left}.${right}`;
|
|
587
|
+
output = replacePropertyAccess(output, nodeSymbol);
|
|
588
|
+
if (nodeIsFunctionReference(node))
|
|
589
|
+
output = asRef(output);
|
|
590
|
+
return output;
|
|
591
|
+
});
|
|
592
|
+
NodeHandler.register(ts7.SyntaxKind.ElementAccessExpression, (node, ctx) => {
|
|
593
|
+
const left = NodeHandler.handle(node.expression);
|
|
594
|
+
let right;
|
|
595
|
+
if (ts7.isStringLiteral(node.argumentExpression)) {
|
|
596
|
+
const leftType = checker.getTypeAtLocation(node.expression);
|
|
597
|
+
right = `"${replaceIdentifier(node.argumentExpression.text, leftType, node.argumentExpression.text)}"`;
|
|
598
|
+
} else {
|
|
599
|
+
right = NodeHandler.handle(node.argumentExpression);
|
|
600
|
+
}
|
|
601
|
+
const asd = ts7.findAncestor(node, (ancestor) => {
|
|
602
|
+
if (ancestor.parent && ts7.isBinaryExpression(ancestor.parent) && ancestor === ancestor.parent.left) {
|
|
603
|
+
const token = ts7.tokenToString(ancestor.parent.operatorToken.kind) || ancestor.parent.operatorToken.getText();
|
|
604
|
+
return assignmentOperators.has(token);
|
|
605
|
+
}
|
|
606
|
+
return false;
|
|
607
|
+
});
|
|
608
|
+
if (!asd && !ts7.isNumericLiteral(node.argumentExpression)) {
|
|
609
|
+
return callUtilFunction("get_property", left, `${right}`);
|
|
610
|
+
}
|
|
611
|
+
return `${left}[${right}]`;
|
|
612
|
+
});
|
|
613
|
+
function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
|
|
614
|
+
currObj ??= [];
|
|
615
|
+
outObjects ??= [];
|
|
616
|
+
funcs ??= [];
|
|
617
|
+
const objectName = ts7.isVariableDeclaration(node.parent) ? NodeHandler.handle(node.parent.name) : ts7.isBinaryExpression(node.parent) && node === node.parent.right ? NodeHandler.handle(node.parent.left) : "";
|
|
618
|
+
function pushObj() {
|
|
619
|
+
if (!currObj?.length)
|
|
620
|
+
return "";
|
|
621
|
+
const res = currObj.filter((s) => s != "").join(",");
|
|
622
|
+
if (res) {
|
|
623
|
+
outObjects?.push(`{ ${res} }`);
|
|
624
|
+
}
|
|
625
|
+
currObj.length = 0;
|
|
626
|
+
return res;
|
|
627
|
+
}
|
|
628
|
+
for (const item of node.properties) {
|
|
629
|
+
if (ts7.isFunctionLike(item)) {
|
|
630
|
+
if (!objectName)
|
|
631
|
+
throw "You can't have method declarations inside an object that is not being assigned to a variable";
|
|
632
|
+
funcs.push(`${objectName}.${NodeHandler.handle(item)}`);
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
if (ts7.isPropertyAssignment(item) && ts7.isFunctionLike(item.initializer)) {
|
|
636
|
+
if (!objectName)
|
|
637
|
+
throw "You can't have method declarations inside an object that is not being assigned to a variable";
|
|
638
|
+
funcs.push(`${objectName}.${NodeHandler.handle(item.name)} = ${NodeHandler.handle(item.initializer)}`);
|
|
639
|
+
continue;
|
|
640
|
+
}
|
|
641
|
+
if (ts7.isSpreadAssignment(item)) {
|
|
642
|
+
if (ts7.isObjectLiteralExpression(item.expression)) {
|
|
643
|
+
handleObjectLiteralExpression(item.expression, ctx, currObj, outObjects);
|
|
644
|
+
continue;
|
|
645
|
+
}
|
|
646
|
+
if (ts7.isIdentifier(item.expression)) {
|
|
647
|
+
pushObj();
|
|
648
|
+
outObjects.push(NodeHandler.handle(item.expression));
|
|
649
|
+
continue;
|
|
650
|
+
}
|
|
651
|
+
if (ts7.isArrayLiteralExpression(item.expression)) {
|
|
652
|
+
pushObj();
|
|
653
|
+
outObjects.push(NodeHandler.handle(item.expression));
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
currObj.push(NodeHandler.handle(item));
|
|
658
|
+
}
|
|
659
|
+
pushObj();
|
|
660
|
+
if (!outObjects.length)
|
|
661
|
+
outObjects.push("{}");
|
|
662
|
+
let output = outObjects[0];
|
|
663
|
+
if (outObjects.length > 1) {
|
|
664
|
+
output = callUtilFunction("assign_objects", output, `[${outObjects.slice(1).join(",")}]`);
|
|
665
|
+
}
|
|
666
|
+
if (funcs.length) {
|
|
667
|
+
output += `
|
|
668
|
+
` + funcs.join(`
|
|
669
|
+
`);
|
|
670
|
+
}
|
|
671
|
+
return output;
|
|
672
|
+
}
|
|
673
|
+
NodeHandler.register(ts7.SyntaxKind.ObjectLiteralExpression, handleObjectLiteralExpression);
|
|
674
|
+
|
|
551
675
|
// src/visitors/expressions.ts
|
|
552
676
|
function hasRestParam(params) {
|
|
553
677
|
if (!params.length)
|
|
554
678
|
return false;
|
|
555
679
|
const lastParam = params[params.length - 1];
|
|
556
|
-
return !!(lastParam.valueDeclaration &&
|
|
680
|
+
return !!(lastParam.valueDeclaration && ts8.isParameter(lastParam.valueDeclaration) && lastParam.valueDeclaration.dotDotDotToken);
|
|
557
681
|
}
|
|
558
682
|
function handleCallArgs(callNode, ctx) {
|
|
559
683
|
const args = callNode.arguments;
|
|
@@ -577,11 +701,11 @@ function handleCallArgs(callNode, ctx) {
|
|
|
577
701
|
}
|
|
578
702
|
}
|
|
579
703
|
for (const arg of args) {
|
|
580
|
-
if (!
|
|
704
|
+
if (!ts8.isSpreadElement(arg)) {
|
|
581
705
|
pushArgs(false, NodeHandler.handle(arg));
|
|
582
706
|
continue;
|
|
583
707
|
}
|
|
584
|
-
if (
|
|
708
|
+
if (ts8.isArrayLiteralExpression(arg.expression)) {
|
|
585
709
|
const arrayItems = [];
|
|
586
710
|
const outArrs = [];
|
|
587
711
|
handleArrayLiteralExpression(arg.expression, ctx, arrayItems, outArrs);
|
|
@@ -633,7 +757,7 @@ function handleCallArgs(callNode, ctx) {
|
|
|
633
757
|
result.push("[]");
|
|
634
758
|
return result;
|
|
635
759
|
}
|
|
636
|
-
NodeHandler.register(
|
|
760
|
+
NodeHandler.register(ts8.SyntaxKind.CallExpression, (node, ctx) => {
|
|
637
761
|
const args = handleCallArgs(node, ctx);
|
|
638
762
|
let name = NodeHandler.handle(node.expression);
|
|
639
763
|
const type = checker.getTypeAtLocation(node.expression);
|
|
@@ -652,28 +776,51 @@ NodeHandler.register(ts7.SyntaxKind.CallExpression, (node, ctx) => {
|
|
|
652
776
|
return name;
|
|
653
777
|
return `${name}(${args.join(", ")})`;
|
|
654
778
|
});
|
|
655
|
-
NodeHandler.register(
|
|
779
|
+
NodeHandler.register(ts8.SyntaxKind.NewExpression, (node, ctx) => {
|
|
656
780
|
const args = handleCallArgs(node, ctx);
|
|
657
781
|
let output = `(new ${NodeHandler.handle(node.expression)}).constructor`;
|
|
658
782
|
if (args.length)
|
|
659
783
|
output += `(${args.join(",")})`;
|
|
660
784
|
return output;
|
|
661
785
|
});
|
|
662
|
-
|
|
786
|
+
function shouldHaveOuterPrefix(node, operator) {
|
|
787
|
+
if (!assignmentOperators.has(operator))
|
|
788
|
+
return false;
|
|
789
|
+
if (!ts8.isIdentifier(node.left))
|
|
790
|
+
return false;
|
|
791
|
+
const functionAncestor = ts8.findAncestor(node.parent, (n) => ts8.isFunctionLike(n));
|
|
792
|
+
if (!functionAncestor)
|
|
793
|
+
return false;
|
|
794
|
+
if (!ts8.findAncestor(functionAncestor.parent, (n) => ts8.isFunctionLike(n)))
|
|
795
|
+
return false;
|
|
796
|
+
const leftSymbol = checker.getSymbolAtLocation(node.left);
|
|
797
|
+
if (!leftSymbol?.valueDeclaration)
|
|
798
|
+
return false;
|
|
799
|
+
return leftSymbol.valueDeclaration.pos < functionAncestor.pos || leftSymbol.valueDeclaration.pos > functionAncestor.end;
|
|
800
|
+
}
|
|
801
|
+
function isAssignmentChain(node, operator) {
|
|
802
|
+
if (!assignmentOperators.has(operator))
|
|
803
|
+
return false;
|
|
804
|
+
if (ts8.isBinaryExpression(node.right) && assignmentOperators.has(ts8.tokenToString(node.right.operatorToken.kind) || ""))
|
|
805
|
+
return true;
|
|
806
|
+
if (ts8.hasOnlyExpressionInitializer(node.parent))
|
|
807
|
+
return true;
|
|
808
|
+
return false;
|
|
809
|
+
}
|
|
810
|
+
NodeHandler.register(ts8.SyntaxKind.BinaryExpression, (node) => {
|
|
663
811
|
let operatorToken = getOperatorToken(node.operatorToken) || node.operatorToken.getText();
|
|
664
|
-
if (
|
|
665
|
-
throw
|
|
666
|
-
}
|
|
812
|
+
if (isAssignmentChain(node, operatorToken))
|
|
813
|
+
throw `Assignment chaining is not supported`;
|
|
667
814
|
let right = NodeHandler.handle(node.right);
|
|
668
815
|
if (nodeIsFunctionReference(node.right))
|
|
669
816
|
right = asRef(right);
|
|
670
|
-
if (
|
|
817
|
+
if (ts8.isPropertyAccessExpression(node.left)) {
|
|
671
818
|
const leftType = checker.getTypeAtLocation(node.left.expression);
|
|
672
819
|
const symbol = leftType.getProperty(node.left.name.text);
|
|
673
|
-
if (symbol?.declarations?.some((decl) =>
|
|
820
|
+
if (symbol?.declarations?.some((decl) => ts8.isSetAccessor(decl))) {
|
|
674
821
|
const objName = NodeHandler.handle(node.left.expression);
|
|
675
822
|
const key = node.left.name.text;
|
|
676
|
-
if (operatorToken !== "=" && symbol.declarations.some((decl) =>
|
|
823
|
+
if (operatorToken !== "=" && symbol.declarations.some((decl) => ts8.isGetAccessor(decl)))
|
|
677
824
|
throw `Can't handle '${operatorToken}' because '${objName}' doesn't have a getter '${key}'`;
|
|
678
825
|
if (operatorToken === "+=" || operatorToken === "-=") {
|
|
679
826
|
right = `${objName}.${key} ${operatorToken[0]} ${right}`;
|
|
@@ -684,14 +831,16 @@ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
|
|
|
684
831
|
}
|
|
685
832
|
}
|
|
686
833
|
let left = NodeHandler.handle(node.left);
|
|
834
|
+
if (shouldHaveOuterPrefix(node, operatorToken))
|
|
835
|
+
left = "outer." + left;
|
|
687
836
|
if (nodeIsFunctionReference(node.left))
|
|
688
837
|
left = asRef(left);
|
|
689
|
-
if (operatorToken === "or" &&
|
|
838
|
+
if (operatorToken === "or" && ts8.hasOnlyExpressionInitializer(node.parent)) {
|
|
690
839
|
return callUtilFunction("or_op", left, right);
|
|
691
840
|
}
|
|
692
841
|
if (operatorToken === "instanceof") {
|
|
693
842
|
const rightSymbol = checker.getSymbolAtLocation(node.right);
|
|
694
|
-
const classIdMember = rightSymbol?.members?.get(
|
|
843
|
+
const classIdMember = rightSymbol?.members?.get(ts8.escapeLeadingUnderscores("classID"));
|
|
695
844
|
if (!classIdMember) {
|
|
696
845
|
throw `Can't handle this 'instanceof' operator because '${right}' doesn't have a 'classID' member, which is needed in GreyScript to check a type`;
|
|
697
846
|
}
|
|
@@ -701,43 +850,45 @@ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node) => {
|
|
|
701
850
|
}
|
|
702
851
|
return `${left}.classID == typeof(${right})`;
|
|
703
852
|
}
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
853
|
+
switch (operatorToken) {
|
|
854
|
+
case "??":
|
|
855
|
+
return callUtilFunction("nullish_coalescing_op", left, right);
|
|
856
|
+
case "??=":
|
|
857
|
+
return `${left} = ${callUtilFunction("nullish_coalescing_op", left, right)}`;
|
|
858
|
+
case "in":
|
|
859
|
+
return `${right}.hasIndex(${left})`;
|
|
860
|
+
case "&":
|
|
861
|
+
return `bitwise("&", ${left}, ${right})`;
|
|
862
|
+
case "|":
|
|
863
|
+
return `bitwise("|", ${left}, ${right})`;
|
|
864
|
+
case "^":
|
|
865
|
+
return `bitwise("^", ${left}, ${right})`;
|
|
866
|
+
case "<<":
|
|
867
|
+
return `bitwise("<<", ${left}, ${right})`;
|
|
868
|
+
case ">>":
|
|
869
|
+
return `bitwise(">>", ${left}, ${right})`;
|
|
870
|
+
case ">>>":
|
|
871
|
+
return `bitwise(">>>", ${left}, ${right})`;
|
|
872
|
+
case "+=":
|
|
873
|
+
case "-=":
|
|
874
|
+
return `${left} = ${left} ${operatorToken[0]} ${right}`;
|
|
722
875
|
}
|
|
723
|
-
if (operatorToken == "+=" || operatorToken == "-=")
|
|
724
|
-
return `${left} = ${left} ${operatorToken[0]} ${right}`;
|
|
725
876
|
if (operatorToken === "**")
|
|
726
877
|
operatorToken = "^";
|
|
727
878
|
return `${left} ${operatorToken} ${right}`;
|
|
728
879
|
});
|
|
729
|
-
NodeHandler.register(
|
|
880
|
+
NodeHandler.register(ts8.SyntaxKind.ParenthesizedExpression, (node) => {
|
|
730
881
|
return `(${NodeHandler.handle(node.expression)})`;
|
|
731
882
|
});
|
|
732
883
|
function handleUnaryExpression(node) {
|
|
733
884
|
const operand = NodeHandler.handle(node.operand);
|
|
734
|
-
const operator =
|
|
885
|
+
const operator = ts8.tokenToString(node.operator);
|
|
735
886
|
if (operator === "++")
|
|
736
887
|
return `${operand} = ${operand} + 1`;
|
|
737
888
|
if (operator === "--")
|
|
738
889
|
return `${operand} = ${operand} - 1`;
|
|
739
890
|
if (operator === "!") {
|
|
740
|
-
if (
|
|
891
|
+
if (ts8.isPrefixUnaryExpression(node.parent) && ts8.tokenToString(node.parent.operator) === "!") {
|
|
741
892
|
return `(not ${operand})`;
|
|
742
893
|
}
|
|
743
894
|
return `not ${operand}`;
|
|
@@ -750,17 +901,17 @@ function handleUnaryExpression(node) {
|
|
|
750
901
|
return `bitwise("~", ${operand})`;
|
|
751
902
|
throw `Couldn't handle this UnaryExpression: ${node.getText()}`;
|
|
752
903
|
}
|
|
753
|
-
NodeHandler.register(
|
|
754
|
-
NodeHandler.register(
|
|
904
|
+
NodeHandler.register(ts8.SyntaxKind.PrefixUnaryExpression, handleUnaryExpression);
|
|
905
|
+
NodeHandler.register(ts8.SyntaxKind.PostfixUnaryExpression, handleUnaryExpression);
|
|
755
906
|
function handleArrayLiteralExpression(node, ctx, itemStrings, out) {
|
|
756
907
|
itemStrings ??= [];
|
|
757
908
|
out ??= [];
|
|
758
909
|
for (const item of node.elements) {
|
|
759
|
-
if (!
|
|
910
|
+
if (!ts8.isSpreadElement(item)) {
|
|
760
911
|
itemStrings.push(NodeHandler.handle(item));
|
|
761
912
|
continue;
|
|
762
913
|
}
|
|
763
|
-
if (
|
|
914
|
+
if (ts8.isArrayLiteralExpression(item.expression)) {
|
|
764
915
|
handleArrayLiteralExpression(item.expression, ctx, itemStrings, out);
|
|
765
916
|
continue;
|
|
766
917
|
}
|
|
@@ -770,14 +921,14 @@ function handleArrayLiteralExpression(node, ctx, itemStrings, out) {
|
|
|
770
921
|
}
|
|
771
922
|
out.push(NodeHandler.handle(item.expression));
|
|
772
923
|
}
|
|
773
|
-
if ((!out.length || itemStrings.length) && !
|
|
924
|
+
if ((!out.length || itemStrings.length) && !ts8.isSpreadElement(node.parent)) {
|
|
774
925
|
out.push(`[${itemStrings.join(",")}]`);
|
|
775
926
|
itemStrings.length = 0;
|
|
776
927
|
}
|
|
777
928
|
return out.join(" + ");
|
|
778
929
|
}
|
|
779
|
-
NodeHandler.register(
|
|
780
|
-
NodeHandler.register(
|
|
930
|
+
NodeHandler.register(ts8.SyntaxKind.ArrayLiteralExpression, handleArrayLiteralExpression);
|
|
931
|
+
NodeHandler.register(ts8.SyntaxKind.TemplateExpression, (node) => {
|
|
781
932
|
const head = NodeHandler.handle(node.head);
|
|
782
933
|
const strings = [
|
|
783
934
|
...head ? [`"${head}"`] : [],
|
|
@@ -786,22 +937,22 @@ NodeHandler.register(ts7.SyntaxKind.TemplateExpression, (node) => {
|
|
|
786
937
|
const output = strings.join(" + ");
|
|
787
938
|
return output;
|
|
788
939
|
});
|
|
789
|
-
NodeHandler.register(
|
|
940
|
+
NodeHandler.register(ts8.SyntaxKind.TemplateHead, (node) => {
|
|
790
941
|
return transformString(node.text);
|
|
791
942
|
});
|
|
792
|
-
NodeHandler.register(
|
|
943
|
+
NodeHandler.register(ts8.SyntaxKind.TemplateSpan, (node) => {
|
|
793
944
|
let output = NodeHandler.handle(node.expression);
|
|
794
|
-
if (
|
|
945
|
+
if (ts8.isBinaryExpression(node.expression))
|
|
795
946
|
output = `str(${output})`;
|
|
796
947
|
if (node.literal.text)
|
|
797
948
|
output += ` + "${transformString(node.literal.text)}"`;
|
|
798
949
|
return output;
|
|
799
950
|
});
|
|
800
|
-
NodeHandler.register(
|
|
951
|
+
NodeHandler.register(ts8.SyntaxKind.NoSubstitutionTemplateLiteral, (node) => {
|
|
801
952
|
return `"${transformString(node.text)}"`;
|
|
802
953
|
});
|
|
803
|
-
NodeHandler.register(
|
|
804
|
-
if (
|
|
954
|
+
NodeHandler.register(ts8.SyntaxKind.ConditionalExpression, (node) => {
|
|
955
|
+
if (ts8.isCallExpression(node.whenTrue) || ts8.isCallExpression(node.whenFalse)) {
|
|
805
956
|
throw "Call expressions are not supported inside conditional expressions yet";
|
|
806
957
|
}
|
|
807
958
|
const condition = NodeHandler.handle(node.condition);
|
|
@@ -809,18 +960,18 @@ NodeHandler.register(ts7.SyntaxKind.ConditionalExpression, (node) => {
|
|
|
809
960
|
const whenFalse = NodeHandler.handle(node.whenFalse);
|
|
810
961
|
return callUtilFunction("conditional_expr", condition, whenTrue, whenFalse);
|
|
811
962
|
});
|
|
812
|
-
NodeHandler.register(
|
|
963
|
+
NodeHandler.register(ts8.SyntaxKind.ExpressionStatement, (node) => {
|
|
813
964
|
return NodeHandler.handle(node.expression);
|
|
814
965
|
});
|
|
815
|
-
NodeHandler.register(
|
|
966
|
+
NodeHandler.register(ts8.SyntaxKind.NonNullExpression, (node) => {
|
|
816
967
|
return NodeHandler.handle(node.expression);
|
|
817
968
|
});
|
|
818
|
-
NodeHandler.register(
|
|
969
|
+
NodeHandler.register(ts8.SyntaxKind.AsExpression, (node) => {
|
|
819
970
|
return NodeHandler.handle(node.expression);
|
|
820
971
|
});
|
|
821
|
-
NodeHandler.register(
|
|
822
|
-
if (!
|
|
823
|
-
throw `Cant handle delete expression for ${
|
|
972
|
+
NodeHandler.register(ts8.SyntaxKind.DeleteExpression, (node) => {
|
|
973
|
+
if (!ts8.isPropertyAccessExpression(node.expression))
|
|
974
|
+
throw `Cant handle delete expression for ${ts8.SyntaxKind[node.expression.kind]}`;
|
|
824
975
|
const pnode = node.expression;
|
|
825
976
|
const left = NodeHandler.handle(pnode.expression);
|
|
826
977
|
const leftType = checker.getTypeAtLocation(pnode.expression);
|
|
@@ -829,7 +980,7 @@ NodeHandler.register(ts7.SyntaxKind.DeleteExpression, (node) => {
|
|
|
829
980
|
});
|
|
830
981
|
|
|
831
982
|
// src/visitors/functions.ts
|
|
832
|
-
import
|
|
983
|
+
import ts9 from "typescript";
|
|
833
984
|
function transpileFunctionBody(node) {
|
|
834
985
|
const params = node.parameters.map((param) => NodeHandler.handle(param)).join(", ");
|
|
835
986
|
const body = node.body ? NodeHandler.handle(node.body) : "";
|
|
@@ -837,7 +988,7 @@ function transpileFunctionBody(node) {
|
|
|
837
988
|
${body}
|
|
838
989
|
end function`;
|
|
839
990
|
}
|
|
840
|
-
NodeHandler.register(
|
|
991
|
+
NodeHandler.register(ts9.SyntaxKind.Block, (node) => {
|
|
841
992
|
const output = node.statements.map((val) => {
|
|
842
993
|
let statement = NodeHandler.handle(val);
|
|
843
994
|
statement = statement.split(`
|
|
@@ -848,38 +999,38 @@ NodeHandler.register(ts8.SyntaxKind.Block, (node) => {
|
|
|
848
999
|
`);
|
|
849
1000
|
return output;
|
|
850
1001
|
});
|
|
851
|
-
NodeHandler.register(
|
|
1002
|
+
NodeHandler.register(ts9.SyntaxKind.MethodDeclaration, (node) => {
|
|
852
1003
|
return `${NodeHandler.handle(node.name)} = ${transpileFunctionBody(node)}`;
|
|
853
1004
|
});
|
|
854
|
-
NodeHandler.register(
|
|
1005
|
+
NodeHandler.register(ts9.SyntaxKind.FunctionDeclaration, (node) => {
|
|
855
1006
|
if (!node.body)
|
|
856
1007
|
return "";
|
|
857
|
-
if (node.modifiers?.some((m) => m.kind ===
|
|
1008
|
+
if (node.modifiers?.some((m) => m.kind === ts9.SyntaxKind.DeclareKeyword))
|
|
858
1009
|
return "";
|
|
859
1010
|
const name = node.name ? node.name.text : "anon";
|
|
860
1011
|
return `${name} = ${transpileFunctionBody(node)}`;
|
|
861
1012
|
});
|
|
862
|
-
NodeHandler.register(
|
|
1013
|
+
NodeHandler.register(ts9.SyntaxKind.ArrowFunction, (node) => {
|
|
863
1014
|
const params = node.parameters.map((param) => NodeHandler.handle(param));
|
|
864
|
-
const body =
|
|
865
|
-
if (
|
|
1015
|
+
const body = ts9.isBlock(node.body) ? NodeHandler.handle(node.body) : ` return ${NodeHandler.handle(node.body)}`;
|
|
1016
|
+
if (ts9.isCallOrNewExpression(node.parent) || ts9.isParenthesizedExpression(node.parent)) {
|
|
866
1017
|
return "@" + createAnonFunction(body, params).name;
|
|
867
1018
|
}
|
|
868
|
-
if (
|
|
1019
|
+
if (ts9.isPropertyAssignment(node.parent) || ts9.isVariableDeclaration(node.parent) || ts9.isBinaryExpression(node.parent) || ts9.isReturnStatement(node.parent)) {
|
|
869
1020
|
return `function(${params.join(", ")})
|
|
870
1021
|
${body}
|
|
871
1022
|
end function`;
|
|
872
1023
|
}
|
|
873
|
-
const kind =
|
|
1024
|
+
const kind = ts9.SyntaxKind[node.parent.kind];
|
|
874
1025
|
throw `This kind of arrow function is not yet supported (parent: ${kind} (${node.parent.kind}))`;
|
|
875
1026
|
});
|
|
876
|
-
NodeHandler.register(
|
|
1027
|
+
NodeHandler.register(ts9.SyntaxKind.FunctionExpression, (node) => {
|
|
877
1028
|
return transpileFunctionBody(node);
|
|
878
1029
|
});
|
|
879
1030
|
|
|
880
1031
|
// src/visitors/identifiers.ts
|
|
881
|
-
import
|
|
882
|
-
NodeHandler.register(
|
|
1032
|
+
import ts10 from "typescript";
|
|
1033
|
+
NodeHandler.register(ts10.SyntaxKind.Identifier, (node, ctx) => {
|
|
883
1034
|
const type = checker.getTypeAtLocation(node);
|
|
884
1035
|
let name = node.text;
|
|
885
1036
|
if (name === "undefined")
|
|
@@ -897,31 +1048,31 @@ NodeHandler.register(ts9.SyntaxKind.Identifier, (node, ctx) => {
|
|
|
897
1048
|
if (ctx.namedImports[ctx.currentFilePath]?.[name]) {
|
|
898
1049
|
name = ctx.namedImports[ctx.currentFilePath][name];
|
|
899
1050
|
}
|
|
900
|
-
if (
|
|
1051
|
+
if (ts10.isCallOrNewExpression(node.parent) && node != node.parent.expression) {
|
|
901
1052
|
if (nodeIsFunctionReference(node, type))
|
|
902
1053
|
name = asRef(name);
|
|
903
1054
|
}
|
|
904
1055
|
return name;
|
|
905
1056
|
});
|
|
906
|
-
NodeHandler.register(
|
|
1057
|
+
NodeHandler.register(ts10.SyntaxKind.Parameter, (node) => {
|
|
907
1058
|
const name = NodeHandler.handle(node.name);
|
|
908
1059
|
if (!node.initializer)
|
|
909
1060
|
return name;
|
|
910
1061
|
const initializer = NodeHandler.handle(node.initializer);
|
|
911
1062
|
const initializerType = checker.getTypeAtLocation(node.initializer);
|
|
912
|
-
if (initializerType.flags ===
|
|
1063
|
+
if (initializerType.flags === ts10.TypeFlags.Object) {
|
|
913
1064
|
throw `You can't initialize parameter '${name}' with an Array or an Object as that won't work in GreyScript and it would be null`;
|
|
914
1065
|
}
|
|
915
1066
|
return `${name} = ${initializer}`;
|
|
916
1067
|
});
|
|
917
|
-
NodeHandler.register(
|
|
918
|
-
NodeHandler.register(
|
|
919
|
-
NodeHandler.register(
|
|
920
|
-
NodeHandler.register(
|
|
921
|
-
NodeHandler.register(
|
|
922
|
-
NodeHandler.register(
|
|
923
|
-
NodeHandler.register(
|
|
924
|
-
const propDeclarationAncestor =
|
|
1068
|
+
NodeHandler.register(ts10.SyntaxKind.NumericLiteral, (node) => node.text);
|
|
1069
|
+
NodeHandler.register(ts10.SyntaxKind.StringLiteral, (node) => `"${transformString(node.text)}"`);
|
|
1070
|
+
NodeHandler.register(ts10.SyntaxKind.NullKeyword, () => "null");
|
|
1071
|
+
NodeHandler.register(ts10.SyntaxKind.UndefinedKeyword, () => "null");
|
|
1072
|
+
NodeHandler.register(ts10.SyntaxKind.FalseKeyword, () => "0");
|
|
1073
|
+
NodeHandler.register(ts10.SyntaxKind.TrueKeyword, () => "1");
|
|
1074
|
+
NodeHandler.register(ts10.SyntaxKind.ThisKeyword, (node) => {
|
|
1075
|
+
const propDeclarationAncestor = ts10.findAncestor(node.parent, (n) => ts10.isPropertyDeclaration(n));
|
|
925
1076
|
if (propDeclarationAncestor) {
|
|
926
1077
|
if (!propDeclarationAncestor.parent.name)
|
|
927
1078
|
throw `Can't handle this 'this' keyword becuase the class doesn't have a name and it's needed for this case`;
|
|
@@ -929,12 +1080,12 @@ NodeHandler.register(ts9.SyntaxKind.ThisKeyword, (node) => {
|
|
|
929
1080
|
}
|
|
930
1081
|
return "self";
|
|
931
1082
|
});
|
|
932
|
-
NodeHandler.register(
|
|
933
|
-
if (
|
|
1083
|
+
NodeHandler.register(ts10.SyntaxKind.SuperKeyword, (node) => {
|
|
1084
|
+
if (ts10.isPropertyAccessExpression(node.parent) || ts10.isElementAccessExpression(node.parent))
|
|
934
1085
|
return "super";
|
|
935
1086
|
return "super.constructor";
|
|
936
1087
|
});
|
|
937
|
-
NodeHandler.register(
|
|
1088
|
+
NodeHandler.register(ts10.SyntaxKind.RegularExpressionLiteral, (node) => {
|
|
938
1089
|
const start = node.text.indexOf("/") + 1;
|
|
939
1090
|
const end = node.text.lastIndexOf("/");
|
|
940
1091
|
const flags = node.text.slice(end + 1);
|
|
@@ -945,7 +1096,7 @@ NodeHandler.register(ts9.SyntaxKind.RegularExpressionLiteral, (node) => {
|
|
|
945
1096
|
|
|
946
1097
|
// src/visitors/imports.ts
|
|
947
1098
|
import path3 from "node:path";
|
|
948
|
-
import
|
|
1099
|
+
import ts11 from "typescript";
|
|
949
1100
|
function importFile(filePath, ctx, returnResult) {
|
|
950
1101
|
let srcPath = path3.resolve(ctx.currentFolder, filePath);
|
|
951
1102
|
if (!path3.extname(srcPath))
|
|
@@ -957,7 +1108,7 @@ function importFile(filePath, ctx, returnResult) {
|
|
|
957
1108
|
}
|
|
958
1109
|
return transpileSourceFile(source, ctx, returnResult);
|
|
959
1110
|
}
|
|
960
|
-
NodeHandler.register(
|
|
1111
|
+
NodeHandler.register(ts11.SyntaxKind.ImportDeclaration, (node, ctx) => {
|
|
961
1112
|
if (!node.importClause) {
|
|
962
1113
|
const moduleName = node.moduleSpecifier.text;
|
|
963
1114
|
const transpiledFile = importFile(moduleName, ctx, true);
|
|
@@ -980,7 +1131,7 @@ NodeHandler.register(ts10.SyntaxKind.ImportDeclaration, (node, ctx) => {
|
|
|
980
1131
|
throw `Can't import default exports yet (imported as ${node.importClause.name.text})`;
|
|
981
1132
|
const bindings = node.importClause.namedBindings;
|
|
982
1133
|
if (bindings) {
|
|
983
|
-
if (
|
|
1134
|
+
if (ts11.isNamespaceImport(bindings)) {
|
|
984
1135
|
ctx.namespaceImports[ctx.currentFilePath]?.add(bindings.name.text);
|
|
985
1136
|
} else {
|
|
986
1137
|
bindings.elements.forEach((el) => {
|
|
@@ -994,130 +1145,6 @@ NodeHandler.register(ts10.SyntaxKind.ImportDeclaration, (node, ctx) => {
|
|
|
994
1145
|
return importFile(moduleSpecifier, ctx);
|
|
995
1146
|
});
|
|
996
1147
|
|
|
997
|
-
// src/visitors/objects.ts
|
|
998
|
-
import ts11 from "typescript";
|
|
999
|
-
var assignmentOperators = new Set([
|
|
1000
|
-
"=",
|
|
1001
|
-
"??=",
|
|
1002
|
-
"||=",
|
|
1003
|
-
"-=",
|
|
1004
|
-
"+="
|
|
1005
|
-
]);
|
|
1006
|
-
function valueIsBeingAssignedToNode(node) {
|
|
1007
|
-
const assignAncestor = ts11.findAncestor(node, (ancestor) => {
|
|
1008
|
-
if (ancestor.parent && ts11.isBinaryExpression(ancestor.parent) && ancestor === ancestor.parent.left) {
|
|
1009
|
-
const token = ts11.tokenToString(ancestor.parent.operatorToken.kind) || ancestor.parent.operatorToken.getText();
|
|
1010
|
-
return assignmentOperators.has(token);
|
|
1011
|
-
}
|
|
1012
|
-
return false;
|
|
1013
|
-
});
|
|
1014
|
-
return !!assignAncestor;
|
|
1015
|
-
}
|
|
1016
|
-
NodeHandler.register(ts11.SyntaxKind.PropertyAccessExpression, (node, ctx) => {
|
|
1017
|
-
const left = NodeHandler.handle(node.expression);
|
|
1018
|
-
let right = NodeHandler.handle(node.name);
|
|
1019
|
-
right = replaceIdentifier(right, checker.getTypeAtLocation(node.expression), right);
|
|
1020
|
-
const nodeSymbol = checker.getSymbolAtLocation(node);
|
|
1021
|
-
if (ctx.namespaceImports[ctx.currentFilePath]?.has(left))
|
|
1022
|
-
return right;
|
|
1023
|
-
let getSafely = !!node.questionDotToken && !ts11.isNonNullExpression(node.parent);
|
|
1024
|
-
const rightType = checker.getTypeAtLocation(node.name);
|
|
1025
|
-
if (rightType.isUnion()) {
|
|
1026
|
-
const hasUndefined = rightType.types.some((t) => t.flags === ts11.TypeFlags.Undefined);
|
|
1027
|
-
if (hasUndefined)
|
|
1028
|
-
getSafely = true;
|
|
1029
|
-
}
|
|
1030
|
-
if (!valueIsBeingAssignedToNode(node) && getSafely)
|
|
1031
|
-
return callUtilFunction("get_property", left, `"${right}"`);
|
|
1032
|
-
let output = `${left}.${right}`;
|
|
1033
|
-
output = replacePropertyAccess(output, nodeSymbol);
|
|
1034
|
-
if (nodeIsFunctionReference(node))
|
|
1035
|
-
output = asRef(output);
|
|
1036
|
-
return output;
|
|
1037
|
-
});
|
|
1038
|
-
NodeHandler.register(ts11.SyntaxKind.ElementAccessExpression, (node, ctx) => {
|
|
1039
|
-
const left = NodeHandler.handle(node.expression);
|
|
1040
|
-
let right;
|
|
1041
|
-
if (ts11.isStringLiteral(node.argumentExpression)) {
|
|
1042
|
-
const leftType = checker.getTypeAtLocation(node.expression);
|
|
1043
|
-
right = `"${replaceIdentifier(node.argumentExpression.text, leftType, node.argumentExpression.text)}"`;
|
|
1044
|
-
} else {
|
|
1045
|
-
right = NodeHandler.handle(node.argumentExpression);
|
|
1046
|
-
}
|
|
1047
|
-
const asd = ts11.findAncestor(node, (ancestor) => {
|
|
1048
|
-
if (ancestor.parent && ts11.isBinaryExpression(ancestor.parent) && ancestor === ancestor.parent.left) {
|
|
1049
|
-
const token = ts11.tokenToString(ancestor.parent.operatorToken.kind) || ancestor.parent.operatorToken.getText();
|
|
1050
|
-
return assignmentOperators.has(token);
|
|
1051
|
-
}
|
|
1052
|
-
return false;
|
|
1053
|
-
});
|
|
1054
|
-
if (!asd && !ts11.isNumericLiteral(node.argumentExpression)) {
|
|
1055
|
-
return callUtilFunction("get_property", left, `${right}`);
|
|
1056
|
-
}
|
|
1057
|
-
return `${left}[${right}]`;
|
|
1058
|
-
});
|
|
1059
|
-
function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
|
|
1060
|
-
currObj ??= [];
|
|
1061
|
-
outObjects ??= [];
|
|
1062
|
-
funcs ??= [];
|
|
1063
|
-
const objectName = ts11.isVariableDeclaration(node.parent) ? NodeHandler.handle(node.parent.name) : ts11.isBinaryExpression(node.parent) && node === node.parent.right ? NodeHandler.handle(node.parent.left) : "";
|
|
1064
|
-
function pushObj() {
|
|
1065
|
-
if (!currObj?.length)
|
|
1066
|
-
return "";
|
|
1067
|
-
const res = currObj.filter((s) => s != "").join(",");
|
|
1068
|
-
if (res) {
|
|
1069
|
-
outObjects?.push(`{ ${res} }`);
|
|
1070
|
-
}
|
|
1071
|
-
currObj.length = 0;
|
|
1072
|
-
return res;
|
|
1073
|
-
}
|
|
1074
|
-
for (const item of node.properties) {
|
|
1075
|
-
if (ts11.isFunctionLike(item)) {
|
|
1076
|
-
if (!objectName)
|
|
1077
|
-
throw "You can't have method declarations inside an object that is not being assigned to a variable";
|
|
1078
|
-
funcs.push(`${objectName}.${NodeHandler.handle(item)}`);
|
|
1079
|
-
continue;
|
|
1080
|
-
}
|
|
1081
|
-
if (ts11.isPropertyAssignment(item) && ts11.isFunctionLike(item.initializer)) {
|
|
1082
|
-
if (!objectName)
|
|
1083
|
-
throw "You can't have method declarations inside an object that is not being assigned to a variable";
|
|
1084
|
-
funcs.push(`${objectName}.${NodeHandler.handle(item.name)} = ${NodeHandler.handle(item.initializer)}`);
|
|
1085
|
-
continue;
|
|
1086
|
-
}
|
|
1087
|
-
if (ts11.isSpreadAssignment(item)) {
|
|
1088
|
-
if (ts11.isObjectLiteralExpression(item.expression)) {
|
|
1089
|
-
handleObjectLiteralExpression(item.expression, ctx, currObj, outObjects);
|
|
1090
|
-
continue;
|
|
1091
|
-
}
|
|
1092
|
-
if (ts11.isIdentifier(item.expression)) {
|
|
1093
|
-
pushObj();
|
|
1094
|
-
outObjects.push(NodeHandler.handle(item.expression));
|
|
1095
|
-
continue;
|
|
1096
|
-
}
|
|
1097
|
-
if (ts11.isArrayLiteralExpression(item.expression)) {
|
|
1098
|
-
pushObj();
|
|
1099
|
-
outObjects.push(NodeHandler.handle(item.expression));
|
|
1100
|
-
continue;
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
currObj.push(NodeHandler.handle(item));
|
|
1104
|
-
}
|
|
1105
|
-
pushObj();
|
|
1106
|
-
if (!outObjects.length)
|
|
1107
|
-
outObjects.push("{}");
|
|
1108
|
-
let output = outObjects[0];
|
|
1109
|
-
if (outObjects.length > 1) {
|
|
1110
|
-
output = callUtilFunction("assign_objects", output, `[${outObjects.slice(1).join(",")}]`);
|
|
1111
|
-
}
|
|
1112
|
-
if (funcs.length) {
|
|
1113
|
-
output += `
|
|
1114
|
-
` + funcs.join(`
|
|
1115
|
-
`);
|
|
1116
|
-
}
|
|
1117
|
-
return output;
|
|
1118
|
-
}
|
|
1119
|
-
NodeHandler.register(ts11.SyntaxKind.ObjectLiteralExpression, handleObjectLiteralExpression);
|
|
1120
|
-
|
|
1121
1148
|
// src/visitors/statements.ts
|
|
1122
1149
|
import ts12 from "typescript";
|
|
1123
1150
|
NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
|