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