@grey-ts/transpiler 2.0.0 → 2.1.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/dist/index.js +258 -188
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import path6 from "node:path";
|
|
|
7
7
|
// src/transpiler.ts
|
|
8
8
|
import * as fs2 from "node:fs";
|
|
9
9
|
import * as path5 from "node:path";
|
|
10
|
-
import
|
|
10
|
+
import ts15 from "typescript";
|
|
11
11
|
|
|
12
12
|
// src/nodeHandler.ts
|
|
13
13
|
import * as path from "node:path";
|
|
@@ -33,9 +33,9 @@ class NodeHandler {
|
|
|
33
33
|
if (!extra)
|
|
34
34
|
return result;
|
|
35
35
|
return [
|
|
36
|
-
...extra.before
|
|
36
|
+
...extra.before,
|
|
37
37
|
result,
|
|
38
|
-
...extra.after
|
|
38
|
+
...extra.after
|
|
39
39
|
].join(`
|
|
40
40
|
`);
|
|
41
41
|
} catch (error) {
|
|
@@ -47,13 +47,13 @@ class NodeHandler {
|
|
|
47
47
|
static addExtraOutput(node, before, after) {
|
|
48
48
|
let extra = this.transpileContext.extraOutput.get(node);
|
|
49
49
|
if (!extra) {
|
|
50
|
-
extra = { before:
|
|
50
|
+
extra = { before: [], after: [] };
|
|
51
51
|
this.transpileContext.extraOutput.set(node, extra);
|
|
52
52
|
}
|
|
53
53
|
if (before)
|
|
54
|
-
extra.before
|
|
54
|
+
extra.before.push(before);
|
|
55
55
|
if (after)
|
|
56
|
-
extra.after
|
|
56
|
+
extra.after.push(after);
|
|
57
57
|
}
|
|
58
58
|
static printLineAndCol(node) {
|
|
59
59
|
const source = node.getSourceFile();
|
|
@@ -299,6 +299,13 @@ var knownOperators = new Set([
|
|
|
299
299
|
"*",
|
|
300
300
|
"/",
|
|
301
301
|
"%",
|
|
302
|
+
"*=",
|
|
303
|
+
"/=",
|
|
304
|
+
"%=",
|
|
305
|
+
"**=",
|
|
306
|
+
"<<=",
|
|
307
|
+
">>=",
|
|
308
|
+
">>>=",
|
|
302
309
|
"~",
|
|
303
310
|
"&",
|
|
304
311
|
"|",
|
|
@@ -416,7 +423,14 @@ var assignmentOperators = new Set([
|
|
|
416
423
|
"??=",
|
|
417
424
|
"||=",
|
|
418
425
|
"-=",
|
|
419
|
-
"+="
|
|
426
|
+
"+=",
|
|
427
|
+
"*=",
|
|
428
|
+
"/=",
|
|
429
|
+
"%=",
|
|
430
|
+
"**=",
|
|
431
|
+
"<<=",
|
|
432
|
+
">>=",
|
|
433
|
+
">>>="
|
|
420
434
|
]);
|
|
421
435
|
function valueIsBeingAssignedToNode(node) {
|
|
422
436
|
if (ts3.hasOnlyExpressionInitializer(node.parent) && node === node.parent.name)
|
|
@@ -450,21 +464,90 @@ NodeHandler.register(ts4.SyntaxKind.ComputedPropertyName, (node) => {
|
|
|
450
464
|
});
|
|
451
465
|
|
|
452
466
|
// src/visitors/classes.ts
|
|
467
|
+
import ts6 from "typescript";
|
|
468
|
+
|
|
469
|
+
// src/visitors/functions.ts
|
|
453
470
|
import ts5 from "typescript";
|
|
454
|
-
|
|
471
|
+
function handleFunctionBodyAndParams(node, ctx) {
|
|
472
|
+
const oldBindingElements = Object.keys(ctx.bindingElements);
|
|
473
|
+
const params = node.parameters.map((param) => NodeHandler.handle(param));
|
|
474
|
+
const newBindingElements = Object.keys(ctx.bindingElements).filter((b) => !oldBindingElements.includes(b));
|
|
475
|
+
const body = !node.body ? "" : ts5.isBlock(node.body) ? NodeHandler.handle(node.body) : ` return ${NodeHandler.handle(node.body)}`;
|
|
476
|
+
for (const bindingElement of newBindingElements) {
|
|
477
|
+
delete ctx.bindingElements[bindingElement];
|
|
478
|
+
}
|
|
479
|
+
const functionOutput = [
|
|
480
|
+
`function${params.length ? `(${params.join(", ")})` : ""}`,
|
|
481
|
+
...body ? [body] : [],
|
|
482
|
+
`end function`
|
|
483
|
+
].join(`
|
|
484
|
+
`);
|
|
485
|
+
return {
|
|
486
|
+
body,
|
|
487
|
+
params,
|
|
488
|
+
functionOutput
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
NodeHandler.register(ts5.SyntaxKind.Block, (node) => {
|
|
492
|
+
const output = node.statements.map((val) => {
|
|
493
|
+
let statement = NodeHandler.handle(val);
|
|
494
|
+
statement = statement.split(`
|
|
495
|
+
`).filter((s) => !!s).map((line) => ` ${line}`).join(`
|
|
496
|
+
`);
|
|
497
|
+
return statement;
|
|
498
|
+
}).filter((s) => !!s).join(`
|
|
499
|
+
`);
|
|
500
|
+
return output;
|
|
501
|
+
});
|
|
502
|
+
NodeHandler.register(ts5.SyntaxKind.MethodDeclaration, (node, ctx) => {
|
|
503
|
+
const func = handleFunctionBodyAndParams(node, ctx);
|
|
504
|
+
return `${NodeHandler.handle(node.name)} = ${func.functionOutput}`;
|
|
505
|
+
});
|
|
506
|
+
NodeHandler.register(ts5.SyntaxKind.FunctionDeclaration, (node, ctx) => {
|
|
507
|
+
if (!node.body)
|
|
508
|
+
return "";
|
|
455
509
|
if (node.modifiers?.some((m) => m.kind === ts5.SyntaxKind.DeclareKeyword))
|
|
456
510
|
return "";
|
|
511
|
+
const func = handleFunctionBodyAndParams(node, ctx);
|
|
512
|
+
const name = node.name ? node.name.text : "anon";
|
|
513
|
+
return `${name} = ${func.functionOutput}`;
|
|
514
|
+
});
|
|
515
|
+
NodeHandler.register(ts5.SyntaxKind.ArrowFunction, (node, ctx) => {
|
|
516
|
+
const func = handleFunctionBodyAndParams(node, ctx);
|
|
517
|
+
if (ts5.isCallOrNewExpression(node.parent) || ts5.isParenthesizedExpression(node.parent)) {
|
|
518
|
+
const mainNode = ts5.findAncestor(node.parent, (n) => n.parent && (ts5.isBlock(n.parent) || ts5.isSourceFile(n.parent)));
|
|
519
|
+
if (!mainNode) {
|
|
520
|
+
return `@${createAnonFunction(func.body, func.params).name}`;
|
|
521
|
+
}
|
|
522
|
+
const anon = createAnonFunction(func.body, func.params, false);
|
|
523
|
+
NodeHandler.addExtraOutput(mainNode, anon.str, null);
|
|
524
|
+
return `@${anon.name}`;
|
|
525
|
+
}
|
|
526
|
+
if (ts5.hasOnlyExpressionInitializer(node.parent) || ts5.isBinaryExpression(node.parent) || ts5.isReturnStatement(node.parent)) {
|
|
527
|
+
return func.functionOutput;
|
|
528
|
+
}
|
|
529
|
+
const kind = ts5.SyntaxKind[node.parent.kind];
|
|
530
|
+
throw `This kind of arrow function is not yet supported (parent: ${kind} (${node.parent.kind}))`;
|
|
531
|
+
});
|
|
532
|
+
NodeHandler.register(ts5.SyntaxKind.FunctionExpression, (node, ctx) => {
|
|
533
|
+
return handleFunctionBodyAndParams(node, ctx).functionOutput;
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
// src/visitors/classes.ts
|
|
537
|
+
NodeHandler.register(ts6.SyntaxKind.ClassDeclaration, (node) => {
|
|
538
|
+
if (node.modifiers?.some((m) => m.kind === ts6.SyntaxKind.DeclareKeyword))
|
|
539
|
+
return "";
|
|
457
540
|
const name = node.name ? node.name.text : "anon";
|
|
458
|
-
const extensions = node.heritageClauses?.filter((h) => h.token ===
|
|
541
|
+
const extensions = node.heritageClauses?.filter((h) => h.token === ts6.SyntaxKind.ExtendsKeyword);
|
|
459
542
|
let output = `${name} = {}`;
|
|
460
543
|
if (extensions?.length && extensions[0].types.length)
|
|
461
544
|
output = `${name} = new ${NodeHandler.handle(extensions[0].types[0].expression)}`;
|
|
462
545
|
const declaredNames = new Set;
|
|
463
546
|
let hasConstructor = false;
|
|
464
547
|
for (const member of node.members) {
|
|
465
|
-
if (
|
|
548
|
+
if (ts6.isFunctionLike(member) && "body" in member && !member.body)
|
|
466
549
|
continue;
|
|
467
|
-
if (
|
|
550
|
+
if (ts6.isSemicolonClassElement(member))
|
|
468
551
|
continue;
|
|
469
552
|
if (member.name) {
|
|
470
553
|
const memberName = NodeHandler.handle(member.name);
|
|
@@ -473,78 +556,67 @@ NodeHandler.register(ts5.SyntaxKind.ClassDeclaration, (node) => {
|
|
|
473
556
|
Modifiers such as 'static' are only for TypeScript for now and are not differentiated in the transpiled version from normal declarations for now`;
|
|
474
557
|
declaredNames.add(memberName);
|
|
475
558
|
}
|
|
476
|
-
if (
|
|
559
|
+
if (ts6.isConstructorDeclaration(member))
|
|
477
560
|
hasConstructor = true;
|
|
478
561
|
output += `
|
|
479
562
|
${name}.${NodeHandler.handle(member)}`;
|
|
480
563
|
}
|
|
481
|
-
if (!hasConstructor && !node.modifiers?.some((m) => m.kind ===
|
|
564
|
+
if (!hasConstructor && !node.modifiers?.some((m) => m.kind === ts6.SyntaxKind.AbstractKeyword))
|
|
482
565
|
output += `
|
|
483
566
|
${name}.constructor = function
|
|
484
567
|
return self
|
|
485
568
|
end function`;
|
|
486
569
|
return output;
|
|
487
570
|
});
|
|
488
|
-
NodeHandler.register(
|
|
571
|
+
NodeHandler.register(ts6.SyntaxKind.Constructor, (node, ctx) => {
|
|
489
572
|
if (!node.body)
|
|
490
573
|
return "";
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
const
|
|
494
|
-
if (param.modifiers) {
|
|
495
|
-
const paramName = NodeHandler.handle(param.name);
|
|
496
|
-
const declaration = ` self.${paramName} = ${paramName}`;
|
|
497
|
-
declaredProperties.push(declaration);
|
|
498
|
-
}
|
|
499
|
-
return res;
|
|
500
|
-
}).join(", ");
|
|
501
|
-
let body = NodeHandler.handle(node.body);
|
|
502
|
-
if (declaredProperties.length) {
|
|
503
|
-
const propertiesStr = declaredProperties.join(`
|
|
574
|
+
const func = handleFunctionBodyAndParams(node, ctx);
|
|
575
|
+
if (ctx.parameterProperties.length) {
|
|
576
|
+
const propertiesStr = ctx.parameterProperties.join(`
|
|
504
577
|
`);
|
|
505
|
-
|
|
578
|
+
ctx.parameterProperties.length = 0;
|
|
579
|
+
const lines = func.body.split(`
|
|
506
580
|
`);
|
|
507
581
|
const superIndex = lines.findIndex((line) => line.includes("super.constructor"));
|
|
508
582
|
if (superIndex !== -1) {
|
|
509
|
-
body = `${lines.slice(0, superIndex + 1).join(`
|
|
583
|
+
func.body = `${lines.slice(0, superIndex + 1).join(`
|
|
510
584
|
`)}
|
|
511
585
|
${propertiesStr}
|
|
512
586
|
${lines.slice(superIndex + 1).join(`
|
|
513
587
|
`)}`;
|
|
514
588
|
} else {
|
|
515
|
-
body = `${propertiesStr}
|
|
516
|
-
${body}`;
|
|
589
|
+
func.body = `${propertiesStr}
|
|
590
|
+
${func.body}`;
|
|
517
591
|
}
|
|
518
592
|
}
|
|
519
|
-
return
|
|
520
|
-
${
|
|
521
|
-
|
|
522
|
-
|
|
593
|
+
return [
|
|
594
|
+
`constructor = function${func.params.length ? `(${func.params.join(", ")})` : ""}`,
|
|
595
|
+
...func.body ? [func.body] : [],
|
|
596
|
+
"\treturn self",
|
|
597
|
+
`end function`
|
|
598
|
+
].join(`
|
|
599
|
+
`);
|
|
523
600
|
});
|
|
524
|
-
NodeHandler.register(
|
|
601
|
+
NodeHandler.register(ts6.SyntaxKind.GetAccessor, (node, ctx) => {
|
|
525
602
|
if (!node.body)
|
|
526
603
|
return "";
|
|
527
|
-
const
|
|
528
|
-
return `${NodeHandler.handle(node.name)} =
|
|
529
|
-
${body}
|
|
530
|
-
end function`;
|
|
604
|
+
const func = handleFunctionBodyAndParams(node, ctx);
|
|
605
|
+
return `${NodeHandler.handle(node.name)} = ${func.functionOutput}`;
|
|
531
606
|
});
|
|
532
|
-
NodeHandler.register(
|
|
607
|
+
NodeHandler.register(ts6.SyntaxKind.SetAccessor, (node, ctx) => {
|
|
533
608
|
if (!node.body)
|
|
534
609
|
return "";
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
return `set_${NodeHandler.handle(node.name)} = function(${params.join(", ")})
|
|
538
|
-
${body}
|
|
539
|
-
end function`;
|
|
610
|
+
const func = handleFunctionBodyAndParams(node, ctx);
|
|
611
|
+
return `set_${NodeHandler.handle(node.name)} = ${func.functionOutput}`;
|
|
540
612
|
});
|
|
541
613
|
|
|
542
614
|
// src/visitors/expressions.ts
|
|
543
|
-
import
|
|
615
|
+
import ts8 from "typescript";
|
|
544
616
|
|
|
545
617
|
// src/call_transformers/callTransformer.ts
|
|
546
618
|
import path3 from "node:path";
|
|
547
|
-
import
|
|
619
|
+
import ts7 from "typescript";
|
|
548
620
|
class CallTransformer {
|
|
549
621
|
static handlers = new Map;
|
|
550
622
|
static register(symbolFullName, handler) {
|
|
@@ -587,7 +659,7 @@ CallTransformer.register("GreyHack.include", (_name, _args, node, ctx) => {
|
|
|
587
659
|
if (!node.arguments.length)
|
|
588
660
|
return "";
|
|
589
661
|
const fileArg = node.arguments[0];
|
|
590
|
-
if (!
|
|
662
|
+
if (!ts7.isStringLiteralLike(fileArg))
|
|
591
663
|
throw "You can't include variables";
|
|
592
664
|
const absPath = path3.resolve(ctx.currentFolder, fileArg.text);
|
|
593
665
|
const sources = getSourceFiles(absPath);
|
|
@@ -620,7 +692,7 @@ function hasRestParam(params) {
|
|
|
620
692
|
if (!params.length)
|
|
621
693
|
return false;
|
|
622
694
|
const lastParam = params[params.length - 1];
|
|
623
|
-
return !!(lastParam.valueDeclaration &&
|
|
695
|
+
return !!(lastParam.valueDeclaration && ts8.isParameter(lastParam.valueDeclaration) && lastParam.valueDeclaration.dotDotDotToken);
|
|
624
696
|
}
|
|
625
697
|
function handleCallArgs(callNode, ctx) {
|
|
626
698
|
const args = callNode.arguments;
|
|
@@ -644,11 +716,11 @@ function handleCallArgs(callNode, ctx) {
|
|
|
644
716
|
}
|
|
645
717
|
}
|
|
646
718
|
for (const arg of args) {
|
|
647
|
-
if (!
|
|
719
|
+
if (!ts8.isSpreadElement(arg)) {
|
|
648
720
|
pushArgs(false, NodeHandler.handle(arg));
|
|
649
721
|
continue;
|
|
650
722
|
}
|
|
651
|
-
if (
|
|
723
|
+
if (ts8.isArrayLiteralExpression(arg.expression)) {
|
|
652
724
|
const arrayItems = [];
|
|
653
725
|
const outArrs = [];
|
|
654
726
|
handleArrayLiteralExpression(arg.expression, ctx, arrayItems, outArrs);
|
|
@@ -700,33 +772,35 @@ function handleCallArgs(callNode, ctx) {
|
|
|
700
772
|
result.push("[]");
|
|
701
773
|
return result;
|
|
702
774
|
}
|
|
703
|
-
NodeHandler.register(
|
|
775
|
+
NodeHandler.register(ts8.SyntaxKind.CallExpression, (node, ctx) => {
|
|
704
776
|
const args = handleCallArgs(node, ctx);
|
|
705
777
|
const name = NodeHandler.handle(node.expression);
|
|
706
778
|
const type = checker.getTypeAtLocation(node.expression);
|
|
707
779
|
const transformed = CallTransformer.handle(type, name, args, node, ctx);
|
|
708
780
|
if (transformed !== null)
|
|
709
781
|
return transformed;
|
|
710
|
-
if (!args.length && !
|
|
782
|
+
if (!args.length && !ts8.isParenthesizedExpression(node.expression))
|
|
711
783
|
return name;
|
|
712
784
|
return `${name}(${args.join(", ")})`;
|
|
713
785
|
});
|
|
714
|
-
NodeHandler.register(
|
|
786
|
+
NodeHandler.register(ts8.SyntaxKind.NewExpression, (node, ctx) => {
|
|
715
787
|
const args = handleCallArgs(node, ctx);
|
|
716
788
|
let output = `(new ${NodeHandler.handle(node.expression)}).constructor`;
|
|
717
789
|
if (args.length)
|
|
718
790
|
output += `(${args.join(",")})`;
|
|
719
791
|
return output;
|
|
720
792
|
});
|
|
721
|
-
function shouldHaveOuterPrefix(node, operator) {
|
|
793
|
+
function shouldHaveOuterPrefix(node, operator, ctx) {
|
|
722
794
|
if (!assignmentOperators.has(operator))
|
|
723
795
|
return false;
|
|
724
|
-
if (!
|
|
796
|
+
if (!ts8.isIdentifier(node.left))
|
|
725
797
|
return false;
|
|
726
|
-
|
|
798
|
+
if (ctx.forceOuterPrefix)
|
|
799
|
+
return true;
|
|
800
|
+
const functionAncestor = ts8.findAncestor(node.parent, (n) => ts8.isFunctionLike(n));
|
|
727
801
|
if (!functionAncestor)
|
|
728
802
|
return false;
|
|
729
|
-
if (!
|
|
803
|
+
if (!ts8.findAncestor(functionAncestor.parent, (n) => ts8.isFunctionLike(n)))
|
|
730
804
|
return false;
|
|
731
805
|
const leftSymbol = checker.getSymbolAtLocation(node.left);
|
|
732
806
|
if (!leftSymbol?.valueDeclaration)
|
|
@@ -736,26 +810,26 @@ function shouldHaveOuterPrefix(node, operator) {
|
|
|
736
810
|
function isAssignmentChain(node, operator) {
|
|
737
811
|
if (!assignmentOperators.has(operator))
|
|
738
812
|
return false;
|
|
739
|
-
if (
|
|
813
|
+
if (ts8.isBinaryExpression(node.right) && assignmentOperators.has(ts8.tokenToString(node.right.operatorToken.kind) || ""))
|
|
740
814
|
return true;
|
|
741
|
-
if (
|
|
815
|
+
if (ts8.hasOnlyExpressionInitializer(node.parent))
|
|
742
816
|
return true;
|
|
743
817
|
return false;
|
|
744
818
|
}
|
|
745
|
-
NodeHandler.register(
|
|
819
|
+
NodeHandler.register(ts8.SyntaxKind.BinaryExpression, (node, ctx) => {
|
|
746
820
|
let operatorToken = getOperatorToken(node.operatorToken) || node.operatorToken.getText();
|
|
747
821
|
if (isAssignmentChain(node, operatorToken))
|
|
748
822
|
throw `Assignment chaining is not supported`;
|
|
749
823
|
let right = NodeHandler.handle(node.right);
|
|
750
824
|
if (nodeIsFunctionReference(node.right))
|
|
751
825
|
right = asRef(right);
|
|
752
|
-
if (
|
|
826
|
+
if (ts8.isPropertyAccessExpression(node.left)) {
|
|
753
827
|
const leftType = checker.getTypeAtLocation(node.left.expression);
|
|
754
828
|
const symbol = leftType.getProperty(node.left.name.text);
|
|
755
|
-
if (symbol?.declarations?.some((decl) =>
|
|
829
|
+
if (symbol?.declarations?.some((decl) => ts8.isSetAccessor(decl))) {
|
|
756
830
|
const objName = NodeHandler.handle(node.left.expression);
|
|
757
831
|
const key = node.left.name.text;
|
|
758
|
-
if (operatorToken !== "=" && symbol.declarations.some((decl) =>
|
|
832
|
+
if (operatorToken !== "=" && symbol.declarations.some((decl) => ts8.isGetAccessor(decl)))
|
|
759
833
|
throw `Can't handle '${operatorToken}' because '${objName}' doesn't have a getter '${key}'`;
|
|
760
834
|
if (operatorToken === "+=" || operatorToken === "-=") {
|
|
761
835
|
right = `${objName}.${key} ${operatorToken[0]} ${right}`;
|
|
@@ -766,11 +840,11 @@ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node, ctx) => {
|
|
|
766
840
|
}
|
|
767
841
|
}
|
|
768
842
|
let left = NodeHandler.handle(node.left);
|
|
769
|
-
if (shouldHaveOuterPrefix(node, operatorToken))
|
|
843
|
+
if (shouldHaveOuterPrefix(node, operatorToken, ctx))
|
|
770
844
|
left = `outer.${left}`;
|
|
771
845
|
if (nodeIsFunctionReference(node.left))
|
|
772
846
|
left = asRef(left);
|
|
773
|
-
if (operatorToken === "or" &&
|
|
847
|
+
if (operatorToken === "or" && ts8.hasOnlyExpressionInitializer(node.parent)) {
|
|
774
848
|
return callUtilFunction("or_op", left, right);
|
|
775
849
|
}
|
|
776
850
|
switch (operatorToken) {
|
|
@@ -802,28 +876,37 @@ NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node, ctx) => {
|
|
|
802
876
|
return `bitwise(">>", ${left}, ${right})`;
|
|
803
877
|
case ">>>":
|
|
804
878
|
return `bitwise(">>>", ${left}, ${right})`;
|
|
879
|
+
case "<<=":
|
|
880
|
+
case ">>=":
|
|
881
|
+
case ">>>=":
|
|
882
|
+
return `${left} = bitwise("${operatorToken.slice(0, -1)}", ${left}, ${right})`;
|
|
883
|
+
case "**=":
|
|
884
|
+
return `${left} = ${left} ^ ${right}`;
|
|
805
885
|
case "+=":
|
|
806
886
|
case "-=":
|
|
887
|
+
case "*=":
|
|
888
|
+
case "/=":
|
|
889
|
+
case "%=":
|
|
807
890
|
return `${left} = ${left} ${operatorToken[0]} ${right}`;
|
|
808
891
|
}
|
|
809
892
|
if (operatorToken === "**")
|
|
810
893
|
operatorToken = "^";
|
|
811
894
|
return `${left} ${operatorToken} ${right}`;
|
|
812
895
|
});
|
|
813
|
-
NodeHandler.register(
|
|
896
|
+
NodeHandler.register(ts8.SyntaxKind.ParenthesizedExpression, (node) => {
|
|
814
897
|
return `(${NodeHandler.handle(node.expression)})`;
|
|
815
898
|
});
|
|
816
899
|
function handleUnaryExpression(node) {
|
|
817
900
|
const operand = NodeHandler.handle(node.operand);
|
|
818
|
-
const operator =
|
|
901
|
+
const operator = ts8.tokenToString(node.operator);
|
|
819
902
|
switch (operator) {
|
|
820
903
|
case "++":
|
|
821
904
|
case "--":
|
|
822
|
-
if (
|
|
905
|
+
if (ts8.hasOnlyExpressionInitializer(node.parent) || ts8.isBinaryExpression(node.parent))
|
|
823
906
|
throw `Operator ${operator} is not supported for this kind of expression yet`;
|
|
824
907
|
return `${operand} = ${operand} ${operator[0]} 1`;
|
|
825
908
|
case "!":
|
|
826
|
-
if (
|
|
909
|
+
if (ts8.isPrefixUnaryExpression(node.parent) && ts8.tokenToString(node.parent.operator) === "!") {
|
|
827
910
|
return `(not ${operand})`;
|
|
828
911
|
}
|
|
829
912
|
return `not ${operand}`;
|
|
@@ -837,17 +920,17 @@ function handleUnaryExpression(node) {
|
|
|
837
920
|
throw `Couldn't handle this UnaryExpression: ${node.getText()}`;
|
|
838
921
|
}
|
|
839
922
|
}
|
|
840
|
-
NodeHandler.register(
|
|
841
|
-
NodeHandler.register(
|
|
923
|
+
NodeHandler.register(ts8.SyntaxKind.PrefixUnaryExpression, handleUnaryExpression);
|
|
924
|
+
NodeHandler.register(ts8.SyntaxKind.PostfixUnaryExpression, handleUnaryExpression);
|
|
842
925
|
function handleArrayLiteralExpression(node, ctx, itemStrings, out) {
|
|
843
926
|
itemStrings ??= [];
|
|
844
927
|
out ??= [];
|
|
845
928
|
for (const item of node.elements) {
|
|
846
|
-
if (!
|
|
929
|
+
if (!ts8.isSpreadElement(item)) {
|
|
847
930
|
itemStrings.push(NodeHandler.handle(item));
|
|
848
931
|
continue;
|
|
849
932
|
}
|
|
850
|
-
if (
|
|
933
|
+
if (ts8.isArrayLiteralExpression(item.expression)) {
|
|
851
934
|
handleArrayLiteralExpression(item.expression, ctx, itemStrings, out);
|
|
852
935
|
continue;
|
|
853
936
|
}
|
|
@@ -857,14 +940,14 @@ function handleArrayLiteralExpression(node, ctx, itemStrings, out) {
|
|
|
857
940
|
}
|
|
858
941
|
out.push(NodeHandler.handle(item.expression));
|
|
859
942
|
}
|
|
860
|
-
if ((!out.length || itemStrings.length) && !
|
|
943
|
+
if ((!out.length || itemStrings.length) && !ts8.isSpreadElement(node.parent)) {
|
|
861
944
|
out.push(`[${itemStrings.join(",")}]`);
|
|
862
945
|
itemStrings.length = 0;
|
|
863
946
|
}
|
|
864
947
|
return out.join(" + ");
|
|
865
948
|
}
|
|
866
|
-
NodeHandler.register(
|
|
867
|
-
NodeHandler.register(
|
|
949
|
+
NodeHandler.register(ts8.SyntaxKind.ArrayLiteralExpression, handleArrayLiteralExpression);
|
|
950
|
+
NodeHandler.register(ts8.SyntaxKind.TemplateExpression, (node) => {
|
|
868
951
|
const head = NodeHandler.handle(node.head);
|
|
869
952
|
const strings = [
|
|
870
953
|
...head ? [`"${head}"`] : [],
|
|
@@ -873,51 +956,54 @@ NodeHandler.register(ts7.SyntaxKind.TemplateExpression, (node) => {
|
|
|
873
956
|
const output = strings.join(" + ");
|
|
874
957
|
return output;
|
|
875
958
|
});
|
|
876
|
-
NodeHandler.register(
|
|
959
|
+
NodeHandler.register(ts8.SyntaxKind.TemplateHead, (node) => {
|
|
877
960
|
return transformString(node.text);
|
|
878
961
|
});
|
|
879
|
-
NodeHandler.register(
|
|
962
|
+
NodeHandler.register(ts8.SyntaxKind.TemplateSpan, (node) => {
|
|
880
963
|
let output = NodeHandler.handle(node.expression);
|
|
881
|
-
if (
|
|
964
|
+
if (ts8.isBinaryExpression(node.expression))
|
|
882
965
|
output = `str(${output})`;
|
|
883
966
|
if (node.literal.text)
|
|
884
967
|
output += ` + "${transformString(node.literal.text)}"`;
|
|
885
968
|
return output;
|
|
886
969
|
});
|
|
887
|
-
NodeHandler.register(
|
|
970
|
+
NodeHandler.register(ts8.SyntaxKind.NoSubstitutionTemplateLiteral, (node) => {
|
|
888
971
|
return `"${transformString(node.text)}"`;
|
|
889
972
|
});
|
|
890
|
-
NodeHandler.register(
|
|
891
|
-
if (
|
|
973
|
+
NodeHandler.register(ts8.SyntaxKind.ConditionalExpression, (node) => {
|
|
974
|
+
if (ts8.isCallExpression(node.whenTrue) || ts8.isCallExpression(node.whenFalse)) {
|
|
892
975
|
throw "Call expressions are not supported inside conditional expressions yet";
|
|
893
976
|
}
|
|
977
|
+
if (ts8.isBinaryExpression(node.whenTrue) || ts8.isBinaryExpression(node.whenFalse)) {
|
|
978
|
+
throw "Binary expressions are not supported inside conditional expressions yet";
|
|
979
|
+
}
|
|
894
980
|
const condition = NodeHandler.handle(node.condition);
|
|
895
981
|
const whenTrue = NodeHandler.handle(node.whenTrue);
|
|
896
982
|
const whenFalse = NodeHandler.handle(node.whenFalse);
|
|
897
983
|
return callUtilFunction("conditional_expr", condition, whenTrue, whenFalse);
|
|
898
984
|
});
|
|
899
|
-
NodeHandler.register(
|
|
985
|
+
NodeHandler.register(ts8.SyntaxKind.ExpressionStatement, (node) => {
|
|
900
986
|
return NodeHandler.handle(node.expression);
|
|
901
987
|
});
|
|
902
|
-
NodeHandler.register(
|
|
988
|
+
NodeHandler.register(ts8.SyntaxKind.NonNullExpression, (node) => {
|
|
903
989
|
return NodeHandler.handle(node.expression);
|
|
904
990
|
});
|
|
905
|
-
NodeHandler.register(
|
|
991
|
+
NodeHandler.register(ts8.SyntaxKind.AsExpression, (node) => {
|
|
906
992
|
return NodeHandler.handle(node.expression);
|
|
907
993
|
});
|
|
908
|
-
NodeHandler.register(
|
|
909
|
-
if (
|
|
994
|
+
NodeHandler.register(ts8.SyntaxKind.DeleteExpression, (node) => {
|
|
995
|
+
if (ts8.isPropertyAccessExpression(node.expression)) {
|
|
910
996
|
const pnode = node.expression;
|
|
911
997
|
const left = NodeHandler.handle(pnode.expression);
|
|
912
998
|
const leftType = checker.getTypeAtLocation(pnode.expression);
|
|
913
999
|
const right = replaceIdentifier(NodeHandler.handle(pnode.name), leftType, pnode.name.text);
|
|
914
1000
|
return `${left}.remove("${right}")`;
|
|
915
1001
|
}
|
|
916
|
-
if (
|
|
1002
|
+
if (ts8.isElementAccessExpression(node.expression)) {
|
|
917
1003
|
const pnode = node.expression;
|
|
918
1004
|
const left = NodeHandler.handle(pnode.expression);
|
|
919
1005
|
let right;
|
|
920
|
-
if (
|
|
1006
|
+
if (ts8.isStringLiteral(pnode.argumentExpression)) {
|
|
921
1007
|
const leftType = checker.getTypeAtLocation(pnode.expression);
|
|
922
1008
|
right = `"${replaceIdentifier(pnode.argumentExpression.text, leftType, pnode.argumentExpression.text)}"`;
|
|
923
1009
|
} else {
|
|
@@ -925,62 +1011,7 @@ NodeHandler.register(ts7.SyntaxKind.DeleteExpression, (node) => {
|
|
|
925
1011
|
}
|
|
926
1012
|
return `${left}.remove(${right})`;
|
|
927
1013
|
}
|
|
928
|
-
throw `Cant handle delete expression for ${
|
|
929
|
-
});
|
|
930
|
-
|
|
931
|
-
// src/visitors/functions.ts
|
|
932
|
-
import ts8 from "typescript";
|
|
933
|
-
function transpileFunctionBody(node) {
|
|
934
|
-
const params = node.parameters.map((param) => NodeHandler.handle(param)).join(", ");
|
|
935
|
-
const body = node.body ? NodeHandler.handle(node.body) : "";
|
|
936
|
-
return `function(${params})
|
|
937
|
-
${body}
|
|
938
|
-
end function`;
|
|
939
|
-
}
|
|
940
|
-
NodeHandler.register(ts8.SyntaxKind.Block, (node) => {
|
|
941
|
-
const output = node.statements.map((val) => {
|
|
942
|
-
let statement = NodeHandler.handle(val);
|
|
943
|
-
statement = statement.split(`
|
|
944
|
-
`).filter((s) => !!s).map((line) => ` ${line}`).join(`
|
|
945
|
-
`);
|
|
946
|
-
return statement;
|
|
947
|
-
}).filter((s) => !!s).join(`
|
|
948
|
-
`);
|
|
949
|
-
return output;
|
|
950
|
-
});
|
|
951
|
-
NodeHandler.register(ts8.SyntaxKind.MethodDeclaration, (node) => {
|
|
952
|
-
return `${NodeHandler.handle(node.name)} = ${transpileFunctionBody(node)}`;
|
|
953
|
-
});
|
|
954
|
-
NodeHandler.register(ts8.SyntaxKind.FunctionDeclaration, (node) => {
|
|
955
|
-
if (!node.body)
|
|
956
|
-
return "";
|
|
957
|
-
if (node.modifiers?.some((m) => m.kind === ts8.SyntaxKind.DeclareKeyword))
|
|
958
|
-
return "";
|
|
959
|
-
const name = node.name ? node.name.text : "anon";
|
|
960
|
-
return `${name} = ${transpileFunctionBody(node)}`;
|
|
961
|
-
});
|
|
962
|
-
NodeHandler.register(ts8.SyntaxKind.ArrowFunction, (node) => {
|
|
963
|
-
const params = node.parameters.map((param) => NodeHandler.handle(param));
|
|
964
|
-
const body = ts8.isBlock(node.body) ? NodeHandler.handle(node.body) : ` return ${NodeHandler.handle(node.body)}`;
|
|
965
|
-
if (ts8.isCallOrNewExpression(node.parent) || ts8.isParenthesizedExpression(node.parent)) {
|
|
966
|
-
const mainNode = ts8.findAncestor(node.parent, (n) => n.parent && (ts8.isBlock(n.parent) || ts8.isSourceFile(n.parent)));
|
|
967
|
-
if (!mainNode) {
|
|
968
|
-
return `@${createAnonFunction(body, params).name}`;
|
|
969
|
-
}
|
|
970
|
-
const anon = createAnonFunction(body, params, false);
|
|
971
|
-
NodeHandler.addExtraOutput(mainNode, anon.str, null);
|
|
972
|
-
return `@${anon.name}`;
|
|
973
|
-
}
|
|
974
|
-
if (ts8.hasOnlyExpressionInitializer(node.parent) || ts8.isBinaryExpression(node.parent) || ts8.isReturnStatement(node.parent)) {
|
|
975
|
-
return `function(${params.join(", ")})
|
|
976
|
-
${body}
|
|
977
|
-
end function`;
|
|
978
|
-
}
|
|
979
|
-
const kind = ts8.SyntaxKind[node.parent.kind];
|
|
980
|
-
throw `This kind of arrow function is not yet supported (parent: ${kind} (${node.parent.kind}))`;
|
|
981
|
-
});
|
|
982
|
-
NodeHandler.register(ts8.SyntaxKind.FunctionExpression, (node) => {
|
|
983
|
-
return transpileFunctionBody(node);
|
|
1014
|
+
throw `Cant handle delete expression for ${ts8.SyntaxKind[node.expression.kind]}`;
|
|
984
1015
|
});
|
|
985
1016
|
|
|
986
1017
|
// src/visitors/identifiers.ts
|
|
@@ -998,14 +1029,22 @@ NodeHandler.register(ts9.SyntaxKind.Identifier, (node, ctx) => {
|
|
|
998
1029
|
if (ctx.namedImports[ctx.currentFilePath] && Object.hasOwn(ctx.namedImports[ctx.currentFilePath], name)) {
|
|
999
1030
|
name = ctx.namedImports[ctx.currentFilePath][name];
|
|
1000
1031
|
}
|
|
1032
|
+
if (Object.hasOwn(ctx.bindingElements, name)) {
|
|
1033
|
+
return ctx.bindingElements[name];
|
|
1034
|
+
}
|
|
1001
1035
|
if (ts9.isCallOrNewExpression(node.parent) && node !== node.parent.expression) {
|
|
1002
1036
|
if (nodeIsFunctionReference(node, type))
|
|
1003
1037
|
name = asRef(name);
|
|
1004
1038
|
}
|
|
1005
1039
|
return name;
|
|
1006
1040
|
});
|
|
1007
|
-
NodeHandler.register(ts9.SyntaxKind.Parameter, (node) => {
|
|
1041
|
+
NodeHandler.register(ts9.SyntaxKind.Parameter, (node, ctx) => {
|
|
1008
1042
|
const name = NodeHandler.handle(node.name);
|
|
1043
|
+
if (node.modifiers && ts9.isConstructorDeclaration(node.parent)) {
|
|
1044
|
+
const paramName = name;
|
|
1045
|
+
const declaration = ` self.${paramName} = ${paramName}`;
|
|
1046
|
+
ctx.parameterProperties.push(declaration);
|
|
1047
|
+
}
|
|
1009
1048
|
if (!node.initializer)
|
|
1010
1049
|
return name;
|
|
1011
1050
|
const initializer = NodeHandler.handle(node.initializer);
|
|
@@ -1202,9 +1241,35 @@ ${funcs.map((func) => `${objectName}.${func}`).join(`
|
|
|
1202
1241
|
}
|
|
1203
1242
|
NodeHandler.register(ts11.SyntaxKind.ObjectLiteralExpression, handleObjectLiteralExpression);
|
|
1204
1243
|
|
|
1205
|
-
// src/visitors/
|
|
1244
|
+
// src/visitors/patterns.ts
|
|
1206
1245
|
import ts12 from "typescript";
|
|
1207
|
-
NodeHandler.register(ts12.SyntaxKind.
|
|
1246
|
+
NodeHandler.register(ts12.SyntaxKind.ArrayBindingPattern, (node, ctx) => {
|
|
1247
|
+
if (!ts12.isParameter(node.parent))
|
|
1248
|
+
throw `This kind of ArrayBindingPattern is not yet supported (parent: ${ts12.SyntaxKind[node.parent.kind]})`;
|
|
1249
|
+
const index = Object.entries(ctx.bindingElements).length;
|
|
1250
|
+
const paramName = `arr${index || ""}`;
|
|
1251
|
+
for (let i = 0;i < node.elements.length; i++) {
|
|
1252
|
+
const element = node.elements[i];
|
|
1253
|
+
if (ts12.isOmittedExpression(element))
|
|
1254
|
+
continue;
|
|
1255
|
+
const name = NodeHandler.handle(element);
|
|
1256
|
+
if (!name || name === "null")
|
|
1257
|
+
continue;
|
|
1258
|
+
ctx.bindingElements[name] = `${paramName}[${i}]`;
|
|
1259
|
+
}
|
|
1260
|
+
return paramName;
|
|
1261
|
+
});
|
|
1262
|
+
NodeHandler.register(ts12.SyntaxKind.BindingElement, (node) => {
|
|
1263
|
+
if (node.initializer)
|
|
1264
|
+
throw "Initializers in BindingElement are not yet supported";
|
|
1265
|
+
if (!ts12.isIdentifier(node.name))
|
|
1266
|
+
throw "Nested binding patterns are not supported";
|
|
1267
|
+
return NodeHandler.handle(node.name);
|
|
1268
|
+
});
|
|
1269
|
+
|
|
1270
|
+
// src/visitors/statements.ts
|
|
1271
|
+
import ts13 from "typescript";
|
|
1272
|
+
NodeHandler.register(ts13.SyntaxKind.ForStatement, (node) => {
|
|
1208
1273
|
if (!node.condition || !node.initializer || !node.incrementor) {
|
|
1209
1274
|
throw "Can't transpile this type of for loop.";
|
|
1210
1275
|
}
|
|
@@ -1214,7 +1279,7 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
|
|
|
1214
1279
|
const statement = NodeHandler.handle(node.statement);
|
|
1215
1280
|
function hasContinue(n) {
|
|
1216
1281
|
if (n.getChildren().some((child) => {
|
|
1217
|
-
if (
|
|
1282
|
+
if (ts13.isContinueStatement(child))
|
|
1218
1283
|
return true;
|
|
1219
1284
|
return hasContinue(child);
|
|
1220
1285
|
})) {
|
|
@@ -1222,7 +1287,7 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
|
|
|
1222
1287
|
}
|
|
1223
1288
|
return false;
|
|
1224
1289
|
}
|
|
1225
|
-
const labelIf =
|
|
1290
|
+
const labelIf = ts13.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
|
|
1226
1291
|
if (!hasContinue(node)) {
|
|
1227
1292
|
return [
|
|
1228
1293
|
`${initializer}`,
|
|
@@ -1253,8 +1318,8 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
|
|
|
1253
1318
|
`);
|
|
1254
1319
|
return output;
|
|
1255
1320
|
});
|
|
1256
|
-
NodeHandler.register(
|
|
1257
|
-
if (!
|
|
1321
|
+
NodeHandler.register(ts13.SyntaxKind.ForOfStatement, (node) => {
|
|
1322
|
+
if (!ts13.isVariableDeclarationList(node.initializer)) {
|
|
1258
1323
|
throw `Can't handle this 'for of' statement as '${NodeHandler.handle(node.initializer)}' is not initialized there`;
|
|
1259
1324
|
}
|
|
1260
1325
|
if (node.initializer.declarations.length > 1) {
|
|
@@ -1262,7 +1327,7 @@ NodeHandler.register(ts12.SyntaxKind.ForOfStatement, (node) => {
|
|
|
1262
1327
|
}
|
|
1263
1328
|
const varName = NodeHandler.handle(node.initializer.declarations[0].name);
|
|
1264
1329
|
const objToLoop = NodeHandler.handle(node.expression);
|
|
1265
|
-
const labelIf =
|
|
1330
|
+
const labelIf = ts13.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
|
|
1266
1331
|
return [
|
|
1267
1332
|
`for ${varName} in ${objToLoop}`,
|
|
1268
1333
|
`${NodeHandler.handle(node.statement)}`,
|
|
@@ -1271,8 +1336,8 @@ NodeHandler.register(ts12.SyntaxKind.ForOfStatement, (node) => {
|
|
|
1271
1336
|
].join(`
|
|
1272
1337
|
`);
|
|
1273
1338
|
});
|
|
1274
|
-
NodeHandler.register(
|
|
1275
|
-
if (!
|
|
1339
|
+
NodeHandler.register(ts13.SyntaxKind.ForInStatement, (node) => {
|
|
1340
|
+
if (!ts13.isVariableDeclarationList(node.initializer)) {
|
|
1276
1341
|
throw `Can't handle this 'for in' statement as '${NodeHandler.handle(node.initializer)}' is not initialized there`;
|
|
1277
1342
|
}
|
|
1278
1343
|
if (node.initializer.declarations.length > 1) {
|
|
@@ -1280,7 +1345,7 @@ NodeHandler.register(ts12.SyntaxKind.ForInStatement, (node) => {
|
|
|
1280
1345
|
}
|
|
1281
1346
|
const varName = NodeHandler.handle(node.initializer.declarations[0].name);
|
|
1282
1347
|
const objToLoop = NodeHandler.handle(node.expression);
|
|
1283
|
-
const labelIf =
|
|
1348
|
+
const labelIf = ts13.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
|
|
1284
1349
|
return [
|
|
1285
1350
|
`for ${varName} in ${objToLoop}.indexes`,
|
|
1286
1351
|
`${NodeHandler.handle(node.statement)}`,
|
|
@@ -1289,19 +1354,19 @@ NodeHandler.register(ts12.SyntaxKind.ForInStatement, (node) => {
|
|
|
1289
1354
|
].join(`
|
|
1290
1355
|
`);
|
|
1291
1356
|
});
|
|
1292
|
-
NodeHandler.register(
|
|
1357
|
+
NodeHandler.register(ts13.SyntaxKind.IfStatement, (node) => {
|
|
1293
1358
|
const condition = NodeHandler.handle(node.expression);
|
|
1294
1359
|
const thenStatement = NodeHandler.handle(node.thenStatement);
|
|
1295
|
-
if (!
|
|
1360
|
+
if (!ts13.isBlock(node.thenStatement) && !ts13.isIfStatement(node.thenStatement) && !ts13.isIfStatement(node.parent)) {
|
|
1296
1361
|
if (!node.elseStatement)
|
|
1297
1362
|
return `if ${condition} then ${thenStatement}`;
|
|
1298
|
-
else if (!
|
|
1363
|
+
else if (!ts13.isBlock(node.elseStatement) && !ts13.isIfStatement(node.elseStatement))
|
|
1299
1364
|
return `if ${condition} then ${thenStatement} else ${NodeHandler.handle(node.elseStatement)}`;
|
|
1300
1365
|
}
|
|
1301
1366
|
let output = `if ${condition} then
|
|
1302
1367
|
${thenStatement.trimStart()}`;
|
|
1303
1368
|
if (node.elseStatement) {
|
|
1304
|
-
if (
|
|
1369
|
+
if (ts13.isIfStatement(node.elseStatement)) {
|
|
1305
1370
|
output += `
|
|
1306
1371
|
else ${NodeHandler.handle(node.elseStatement)}`;
|
|
1307
1372
|
return output;
|
|
@@ -1315,9 +1380,9 @@ else
|
|
|
1315
1380
|
end if`;
|
|
1316
1381
|
return output;
|
|
1317
1382
|
});
|
|
1318
|
-
NodeHandler.register(
|
|
1383
|
+
NodeHandler.register(ts13.SyntaxKind.WhileStatement, (node) => {
|
|
1319
1384
|
const expression = NodeHandler.handle(node.expression);
|
|
1320
|
-
const labelIf =
|
|
1385
|
+
const labelIf = ts13.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
|
|
1321
1386
|
return [
|
|
1322
1387
|
`while ${expression}`,
|
|
1323
1388
|
` ${NodeHandler.handle(node.statement).trimStart()}`,
|
|
@@ -1326,9 +1391,9 @@ NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node) => {
|
|
|
1326
1391
|
].join(`
|
|
1327
1392
|
`);
|
|
1328
1393
|
});
|
|
1329
|
-
NodeHandler.register(
|
|
1394
|
+
NodeHandler.register(ts13.SyntaxKind.DoStatement, (node) => {
|
|
1330
1395
|
const expression = NodeHandler.handle(node.expression);
|
|
1331
|
-
const labelIf =
|
|
1396
|
+
const labelIf = ts13.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
|
|
1332
1397
|
return [
|
|
1333
1398
|
`did_once = 0`,
|
|
1334
1399
|
`while not did_once or ${expression}`,
|
|
@@ -1339,38 +1404,38 @@ NodeHandler.register(ts12.SyntaxKind.DoStatement, (node) => {
|
|
|
1339
1404
|
].join(`
|
|
1340
1405
|
`);
|
|
1341
1406
|
});
|
|
1342
|
-
NodeHandler.register(
|
|
1407
|
+
NodeHandler.register(ts13.SyntaxKind.ContinueStatement, (_node) => {
|
|
1343
1408
|
return "continue";
|
|
1344
1409
|
});
|
|
1345
|
-
NodeHandler.register(
|
|
1410
|
+
NodeHandler.register(ts13.SyntaxKind.BreakStatement, (node) => {
|
|
1346
1411
|
if (node.label) {
|
|
1347
|
-
if (!
|
|
1412
|
+
if (!ts13.isBlock(node.parent))
|
|
1348
1413
|
throw "A break statement with a label must be in a block";
|
|
1349
1414
|
return `${NodeHandler.handle(node.label)}Broke = 1
|
|
1350
1415
|
break`;
|
|
1351
1416
|
}
|
|
1352
1417
|
return "break";
|
|
1353
1418
|
});
|
|
1354
|
-
NodeHandler.register(
|
|
1419
|
+
NodeHandler.register(ts13.SyntaxKind.ReturnStatement, (node) => {
|
|
1355
1420
|
if (!node.expression) {
|
|
1356
|
-
if (
|
|
1421
|
+
if (ts13.findAncestor(node, (n) => ts13.isConstructorDeclaration(n)) && !ts13.findAncestor(node, (n) => ts13.isFunctionLike(n))) {
|
|
1357
1422
|
return "return self";
|
|
1358
1423
|
}
|
|
1359
1424
|
return "return";
|
|
1360
1425
|
}
|
|
1361
1426
|
return `return ${NodeHandler.handle(node.expression)}`;
|
|
1362
1427
|
});
|
|
1363
|
-
NodeHandler.register(
|
|
1428
|
+
NodeHandler.register(ts13.SyntaxKind.LabeledStatement, (node) => {
|
|
1364
1429
|
return `${NodeHandler.handle(node.label)}Broke = 0
|
|
1365
1430
|
${NodeHandler.handle(node.statement)}`;
|
|
1366
1431
|
});
|
|
1367
1432
|
|
|
1368
1433
|
// src/visitors/variables.ts
|
|
1369
|
-
import
|
|
1434
|
+
import ts14 from "typescript";
|
|
1370
1435
|
function handleVariableDeclaration(node) {
|
|
1371
1436
|
const left = NodeHandler.handle(node.name);
|
|
1372
1437
|
const initializerType = node.initializer ? checker.getTypeAtLocation(node.initializer) : undefined;
|
|
1373
|
-
if (
|
|
1438
|
+
if (ts14.isPropertyDeclaration(node) && initializerType?.flags === ts14.TypeFlags.Object && !node.modifiers?.some((mod) => mod.kind === ts14.SyntaxKind.StaticKeyword) && !ts14.isFunctionLike(node.initializer)) {
|
|
1374
1439
|
console.warn(`You shouldn't initialize '${left}' with an Array or an Object because in GreyScript, every instantiation refers to the same '${left}' variable.
|
|
1375
1440
|
Initialize them in the constructor instead`);
|
|
1376
1441
|
}
|
|
@@ -1380,18 +1445,18 @@ Initialize them in the constructor instead`);
|
|
|
1380
1445
|
}
|
|
1381
1446
|
return `${left} = ${right}`;
|
|
1382
1447
|
}
|
|
1383
|
-
NodeHandler.register(
|
|
1448
|
+
NodeHandler.register(ts14.SyntaxKind.VariableDeclarationList, (node) => {
|
|
1384
1449
|
return node.declarations.map((decl) => handleVariableDeclaration(decl)).join(`
|
|
1385
1450
|
`);
|
|
1386
1451
|
});
|
|
1387
|
-
NodeHandler.register(
|
|
1388
|
-
if (node.modifiers?.some((modifier) => modifier.kind ===
|
|
1452
|
+
NodeHandler.register(ts14.SyntaxKind.VariableStatement, (node) => {
|
|
1453
|
+
if (node.modifiers?.some((modifier) => modifier.kind === ts14.SyntaxKind.DeclareKeyword))
|
|
1389
1454
|
return "";
|
|
1390
1455
|
return NodeHandler.handle(node.declarationList);
|
|
1391
1456
|
});
|
|
1392
|
-
NodeHandler.register(
|
|
1393
|
-
NodeHandler.register(
|
|
1394
|
-
NodeHandler.register(
|
|
1457
|
+
NodeHandler.register(ts14.SyntaxKind.VariableDeclaration, handleVariableDeclaration);
|
|
1458
|
+
NodeHandler.register(ts14.SyntaxKind.PropertyDeclaration, handleVariableDeclaration);
|
|
1459
|
+
NodeHandler.register(ts14.SyntaxKind.EnumDeclaration, (node) => {
|
|
1395
1460
|
const members = [];
|
|
1396
1461
|
function addMember(name, initializer) {
|
|
1397
1462
|
members.push(`${name}: ${initializer}`);
|
|
@@ -1401,7 +1466,7 @@ NodeHandler.register(ts13.SyntaxKind.EnumDeclaration, (node) => {
|
|
|
1401
1466
|
}
|
|
1402
1467
|
node.members.forEach((member, index) => {
|
|
1403
1468
|
let name = NodeHandler.handle(member.name);
|
|
1404
|
-
if (!
|
|
1469
|
+
if (!ts14.isStringLiteral(member.name))
|
|
1405
1470
|
name = `"${name}"`;
|
|
1406
1471
|
if (member.initializer) {
|
|
1407
1472
|
addMember(name, NodeHandler.handle(member.initializer));
|
|
@@ -1880,9 +1945,12 @@ function createAnonFunction(body, params, insertToUtils = true) {
|
|
|
1880
1945
|
const defaultParams = new Array(3).fill(0).map((_, i) => `param${i}`);
|
|
1881
1946
|
const nextName = `func_${anonFunctionsCreated}`;
|
|
1882
1947
|
const paramString = Object.assign(defaultParams, params).join(",");
|
|
1883
|
-
const result =
|
|
1884
|
-
${
|
|
1885
|
-
|
|
1948
|
+
const result = [
|
|
1949
|
+
`${nextName} = function(${paramString})`,
|
|
1950
|
+
...body ? [body] : [],
|
|
1951
|
+
`end function`
|
|
1952
|
+
].join(`
|
|
1953
|
+
`);
|
|
1886
1954
|
anonFunctionsCreated++;
|
|
1887
1955
|
if (insertToUtils)
|
|
1888
1956
|
utilitiesToInsert.set(nextName, result);
|
|
@@ -1896,7 +1964,9 @@ function createContext(currentFileName = "file.ts") {
|
|
|
1896
1964
|
namespaceImports: {},
|
|
1897
1965
|
visitedFiles: new Set,
|
|
1898
1966
|
output: [],
|
|
1899
|
-
extraOutput: new Map
|
|
1967
|
+
extraOutput: new Map,
|
|
1968
|
+
bindingElements: {},
|
|
1969
|
+
parameterProperties: []
|
|
1900
1970
|
};
|
|
1901
1971
|
}
|
|
1902
1972
|
function transpileProgram(entryFileRelativePath) {
|
|
@@ -1909,15 +1979,15 @@ function transpileProgram(entryFileRelativePath) {
|
|
|
1909
1979
|
}
|
|
1910
1980
|
let start = Date.now();
|
|
1911
1981
|
const tsconfigPath = `${findProjectRoot(process.cwd(), "tsconfig.json")}/tsconfig.json`;
|
|
1912
|
-
const res =
|
|
1913
|
-
const parsed =
|
|
1982
|
+
const res = ts15.readConfigFile(tsconfigPath, ts15.sys.readFile);
|
|
1983
|
+
const parsed = ts15.parseJsonConfigFileContent(res.config, ts15.sys, path5.dirname(tsconfigPath));
|
|
1914
1984
|
if (!parsed.options.types)
|
|
1915
1985
|
parsed.options.types = [];
|
|
1916
1986
|
if (!parsed.options.types.includes("@grey-ts/types")) {
|
|
1917
1987
|
parsed.options.types.push("@grey-ts/types");
|
|
1918
1988
|
}
|
|
1919
1989
|
parsed.options.noLib = true;
|
|
1920
|
-
program =
|
|
1990
|
+
program = ts15.createProgram({
|
|
1921
1991
|
rootNames: parsed.fileNames,
|
|
1922
1992
|
options: parsed.options
|
|
1923
1993
|
});
|