@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.
Files changed (2) hide show
  1. package/dist/index.js +258 -188
  2. 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 ts14 from "typescript";
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 ? [extra.before] : [],
36
+ ...extra.before,
37
37
  result,
38
- ...extra.after ? [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: "", after: "" };
50
+ extra = { before: [], after: [] };
51
51
  this.transpileContext.extraOutput.set(node, extra);
52
52
  }
53
53
  if (before)
54
- extra.before += before;
54
+ extra.before.push(before);
55
55
  if (after)
56
- extra.after += 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
- NodeHandler.register(ts5.SyntaxKind.ClassDeclaration, (node) => {
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 === ts5.SyntaxKind.ExtendsKeyword);
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 (ts5.isFunctionLike(member) && "body" in member && !member.body)
548
+ if (ts6.isFunctionLike(member) && "body" in member && !member.body)
466
549
  continue;
467
- if (ts5.isSemicolonClassElement(member))
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 (ts5.isConstructorDeclaration(member))
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 === ts5.SyntaxKind.AbstractKeyword))
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(ts5.SyntaxKind.Constructor, (node) => {
571
+ NodeHandler.register(ts6.SyntaxKind.Constructor, (node, ctx) => {
489
572
  if (!node.body)
490
573
  return "";
491
- const declaredProperties = [];
492
- const params = node.parameters.map((param) => {
493
- const res = NodeHandler.handle(param);
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
- const lines = body.split(`
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 `constructor = function(${params})
520
- ${body}
521
- return self
522
- end function`;
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(ts5.SyntaxKind.GetAccessor, (node) => {
601
+ NodeHandler.register(ts6.SyntaxKind.GetAccessor, (node, ctx) => {
525
602
  if (!node.body)
526
603
  return "";
527
- const body = NodeHandler.handle(node.body);
528
- return `${NodeHandler.handle(node.name)} = function
529
- ${body}
530
- end function`;
604
+ const func = handleFunctionBodyAndParams(node, ctx);
605
+ return `${NodeHandler.handle(node.name)} = ${func.functionOutput}`;
531
606
  });
532
- NodeHandler.register(ts5.SyntaxKind.SetAccessor, (node) => {
607
+ NodeHandler.register(ts6.SyntaxKind.SetAccessor, (node, ctx) => {
533
608
  if (!node.body)
534
609
  return "";
535
- const body = NodeHandler.handle(node.body);
536
- const params = node.parameters.map((param) => NodeHandler.handle(param));
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 ts7 from "typescript";
615
+ import ts8 from "typescript";
544
616
 
545
617
  // src/call_transformers/callTransformer.ts
546
618
  import path3 from "node:path";
547
- import ts6 from "typescript";
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 (!ts6.isStringLiteralLike(fileArg))
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 && ts7.isParameter(lastParam.valueDeclaration) && lastParam.valueDeclaration.dotDotDotToken);
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 (!ts7.isSpreadElement(arg)) {
719
+ if (!ts8.isSpreadElement(arg)) {
648
720
  pushArgs(false, NodeHandler.handle(arg));
649
721
  continue;
650
722
  }
651
- if (ts7.isArrayLiteralExpression(arg.expression)) {
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(ts7.SyntaxKind.CallExpression, (node, ctx) => {
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 && !ts7.isParenthesizedExpression(node.expression))
782
+ if (!args.length && !ts8.isParenthesizedExpression(node.expression))
711
783
  return name;
712
784
  return `${name}(${args.join(", ")})`;
713
785
  });
714
- NodeHandler.register(ts7.SyntaxKind.NewExpression, (node, ctx) => {
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 (!ts7.isIdentifier(node.left))
796
+ if (!ts8.isIdentifier(node.left))
725
797
  return false;
726
- const functionAncestor = ts7.findAncestor(node.parent, (n) => ts7.isFunctionLike(n));
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 (!ts7.findAncestor(functionAncestor.parent, (n) => ts7.isFunctionLike(n)))
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 (ts7.isBinaryExpression(node.right) && assignmentOperators.has(ts7.tokenToString(node.right.operatorToken.kind) || ""))
813
+ if (ts8.isBinaryExpression(node.right) && assignmentOperators.has(ts8.tokenToString(node.right.operatorToken.kind) || ""))
740
814
  return true;
741
- if (ts7.hasOnlyExpressionInitializer(node.parent))
815
+ if (ts8.hasOnlyExpressionInitializer(node.parent))
742
816
  return true;
743
817
  return false;
744
818
  }
745
- NodeHandler.register(ts7.SyntaxKind.BinaryExpression, (node, ctx) => {
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 (ts7.isPropertyAccessExpression(node.left)) {
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) => ts7.isSetAccessor(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) => ts7.isGetAccessor(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" && ts7.hasOnlyExpressionInitializer(node.parent)) {
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(ts7.SyntaxKind.ParenthesizedExpression, (node) => {
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 = ts7.tokenToString(node.operator);
901
+ const operator = ts8.tokenToString(node.operator);
819
902
  switch (operator) {
820
903
  case "++":
821
904
  case "--":
822
- if (ts7.hasOnlyExpressionInitializer(node.parent) || ts7.isBinaryExpression(node.parent))
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 (ts7.isPrefixUnaryExpression(node.parent) && ts7.tokenToString(node.parent.operator) === "!") {
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(ts7.SyntaxKind.PrefixUnaryExpression, handleUnaryExpression);
841
- NodeHandler.register(ts7.SyntaxKind.PostfixUnaryExpression, handleUnaryExpression);
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 (!ts7.isSpreadElement(item)) {
929
+ if (!ts8.isSpreadElement(item)) {
847
930
  itemStrings.push(NodeHandler.handle(item));
848
931
  continue;
849
932
  }
850
- if (ts7.isArrayLiteralExpression(item.expression)) {
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) && !ts7.isSpreadElement(node.parent)) {
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(ts7.SyntaxKind.ArrayLiteralExpression, handleArrayLiteralExpression);
867
- NodeHandler.register(ts7.SyntaxKind.TemplateExpression, (node) => {
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(ts7.SyntaxKind.TemplateHead, (node) => {
959
+ NodeHandler.register(ts8.SyntaxKind.TemplateHead, (node) => {
877
960
  return transformString(node.text);
878
961
  });
879
- NodeHandler.register(ts7.SyntaxKind.TemplateSpan, (node) => {
962
+ NodeHandler.register(ts8.SyntaxKind.TemplateSpan, (node) => {
880
963
  let output = NodeHandler.handle(node.expression);
881
- if (ts7.isBinaryExpression(node.expression))
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(ts7.SyntaxKind.NoSubstitutionTemplateLiteral, (node) => {
970
+ NodeHandler.register(ts8.SyntaxKind.NoSubstitutionTemplateLiteral, (node) => {
888
971
  return `"${transformString(node.text)}"`;
889
972
  });
890
- NodeHandler.register(ts7.SyntaxKind.ConditionalExpression, (node) => {
891
- if (ts7.isCallExpression(node.whenTrue) || ts7.isCallExpression(node.whenFalse)) {
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(ts7.SyntaxKind.ExpressionStatement, (node) => {
985
+ NodeHandler.register(ts8.SyntaxKind.ExpressionStatement, (node) => {
900
986
  return NodeHandler.handle(node.expression);
901
987
  });
902
- NodeHandler.register(ts7.SyntaxKind.NonNullExpression, (node) => {
988
+ NodeHandler.register(ts8.SyntaxKind.NonNullExpression, (node) => {
903
989
  return NodeHandler.handle(node.expression);
904
990
  });
905
- NodeHandler.register(ts7.SyntaxKind.AsExpression, (node) => {
991
+ NodeHandler.register(ts8.SyntaxKind.AsExpression, (node) => {
906
992
  return NodeHandler.handle(node.expression);
907
993
  });
908
- NodeHandler.register(ts7.SyntaxKind.DeleteExpression, (node) => {
909
- if (ts7.isPropertyAccessExpression(node.expression)) {
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 (ts7.isElementAccessExpression(node.expression)) {
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 (ts7.isStringLiteral(pnode.argumentExpression)) {
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 ${ts7.SyntaxKind[node.expression.kind]}`;
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/statements.ts
1244
+ // src/visitors/patterns.ts
1206
1245
  import ts12 from "typescript";
1207
- NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
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 (ts12.isContinueStatement(child))
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 = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
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(ts12.SyntaxKind.ForOfStatement, (node) => {
1257
- if (!ts12.isVariableDeclarationList(node.initializer)) {
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 = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
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(ts12.SyntaxKind.ForInStatement, (node) => {
1275
- if (!ts12.isVariableDeclarationList(node.initializer)) {
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 = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
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(ts12.SyntaxKind.IfStatement, (node) => {
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 (!ts12.isBlock(node.thenStatement) && !ts12.isIfStatement(node.thenStatement) && !ts12.isIfStatement(node.parent)) {
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 (!ts12.isBlock(node.elseStatement) && !ts12.isIfStatement(node.elseStatement))
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 (ts12.isIfStatement(node.elseStatement)) {
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(ts12.SyntaxKind.WhileStatement, (node) => {
1383
+ NodeHandler.register(ts13.SyntaxKind.WhileStatement, (node) => {
1319
1384
  const expression = NodeHandler.handle(node.expression);
1320
- const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
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(ts12.SyntaxKind.DoStatement, (node) => {
1394
+ NodeHandler.register(ts13.SyntaxKind.DoStatement, (node) => {
1330
1395
  const expression = NodeHandler.handle(node.expression);
1331
- const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
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(ts12.SyntaxKind.ContinueStatement, (_node) => {
1407
+ NodeHandler.register(ts13.SyntaxKind.ContinueStatement, (_node) => {
1343
1408
  return "continue";
1344
1409
  });
1345
- NodeHandler.register(ts12.SyntaxKind.BreakStatement, (node) => {
1410
+ NodeHandler.register(ts13.SyntaxKind.BreakStatement, (node) => {
1346
1411
  if (node.label) {
1347
- if (!ts12.isBlock(node.parent))
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(ts12.SyntaxKind.ReturnStatement, (node) => {
1419
+ NodeHandler.register(ts13.SyntaxKind.ReturnStatement, (node) => {
1355
1420
  if (!node.expression) {
1356
- if (ts12.findAncestor(node, (n) => ts12.isConstructorDeclaration(n)) && !ts12.findAncestor(node, (n) => ts12.isFunctionLike(n))) {
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(ts12.SyntaxKind.LabeledStatement, (node) => {
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 ts13 from "typescript";
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 (ts13.isPropertyDeclaration(node) && initializerType?.flags === ts13.TypeFlags.Object && !node.modifiers?.some((mod) => mod.kind === ts13.SyntaxKind.StaticKeyword) && !ts13.isFunctionLike(node.initializer)) {
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(ts13.SyntaxKind.VariableDeclarationList, (node) => {
1448
+ NodeHandler.register(ts14.SyntaxKind.VariableDeclarationList, (node) => {
1384
1449
  return node.declarations.map((decl) => handleVariableDeclaration(decl)).join(`
1385
1450
  `);
1386
1451
  });
1387
- NodeHandler.register(ts13.SyntaxKind.VariableStatement, (node) => {
1388
- if (node.modifiers?.some((modifier) => modifier.kind === ts13.SyntaxKind.DeclareKeyword))
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(ts13.SyntaxKind.VariableDeclaration, handleVariableDeclaration);
1393
- NodeHandler.register(ts13.SyntaxKind.PropertyDeclaration, handleVariableDeclaration);
1394
- NodeHandler.register(ts13.SyntaxKind.EnumDeclaration, (node) => {
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 (!ts13.isStringLiteral(member.name))
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 = `${nextName} = function(${paramString})
1884
- ${body}
1885
- end function`;
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 = ts14.readConfigFile(tsconfigPath, ts14.sys.readFile);
1913
- const parsed = ts14.parseJsonConfigFileContent(res.config, ts14.sys, path5.dirname(tsconfigPath));
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 = ts14.createProgram({
1990
+ program = ts15.createProgram({
1921
1991
  rootNames: parsed.fileNames,
1922
1992
  options: parsed.options
1923
1993
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grey-ts/transpiler",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Transpiles TypeScript into GreyScript",
5
5
  "author": "Okka",
6
6
  "module": "src/index.ts",