typescript-to-lua 1.6.2 → 1.7.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 (101) hide show
  1. package/dist/CompilerOptions.d.ts +1 -0
  2. package/dist/cli/diagnostics.d.ts +3 -0
  3. package/dist/cli/diagnostics.js +2 -1
  4. package/dist/cli/parse.d.ts +1 -1
  5. package/dist/cli/parse.js +47 -11
  6. package/dist/lualib/ArraySlice.lua +10 -2
  7. package/dist/lualib/ArraySplice.lua +5 -1
  8. package/dist/lualib/Generator.lua +8 -1
  9. package/dist/lualib/ParseFloat.lua +5 -1
  10. package/dist/lualib/SparseArraySpread.lua +5 -1
  11. package/dist/lualib/StringCharCodeAt.lua +5 -1
  12. package/dist/lualib/lualib_bundle.lua +38 -7
  13. package/dist/lualib-build/plugin.js +1 -2
  14. package/dist/measure-performance.d.ts +15 -0
  15. package/dist/measure-performance.js +83 -0
  16. package/dist/transformation/builtins/array.js +2 -1
  17. package/dist/transformation/builtins/function.js +1 -1
  18. package/dist/transformation/builtins/global.d.ts +1 -1
  19. package/dist/transformation/builtins/global.js +13 -12
  20. package/dist/transformation/builtins/index.d.ts +2 -2
  21. package/dist/transformation/builtins/index.js +87 -89
  22. package/dist/transformation/builtins/object.d.ts +1 -1
  23. package/dist/transformation/builtins/object.js +4 -4
  24. package/dist/transformation/builtins/promise.js +4 -2
  25. package/dist/transformation/builtins/string.js +2 -0
  26. package/dist/transformation/context/context.d.ts +15 -0
  27. package/dist/transformation/context/context.js +66 -24
  28. package/dist/transformation/context/visitors.d.ts +1 -1
  29. package/dist/transformation/index.js +6 -5
  30. package/dist/transformation/utils/annotations.d.ts +1 -17
  31. package/dist/transformation/utils/annotations.js +48 -88
  32. package/dist/transformation/utils/assignment-validation.js +27 -23
  33. package/dist/transformation/utils/diagnostics.d.ts +1 -4
  34. package/dist/transformation/utils/diagnostics.js +2 -3
  35. package/dist/transformation/utils/function-context.d.ts +1 -1
  36. package/dist/transformation/utils/function-context.js +57 -51
  37. package/dist/transformation/utils/language-extensions.d.ts +57 -51
  38. package/dist/transformation/utils/language-extensions.js +99 -119
  39. package/dist/transformation/utils/lualib.d.ts +0 -1
  40. package/dist/transformation/utils/lualib.js +2 -8
  41. package/dist/transformation/utils/safe-names.d.ts +1 -1
  42. package/dist/transformation/utils/safe-names.js +3 -6
  43. package/dist/transformation/utils/scope.d.ts +0 -2
  44. package/dist/transformation/utils/scope.js +10 -27
  45. package/dist/transformation/utils/symbols.d.ts +1 -1
  46. package/dist/transformation/utils/symbols.js +7 -20
  47. package/dist/transformation/utils/typescript/index.d.ts +1 -0
  48. package/dist/transformation/utils/typescript/index.js +2 -1
  49. package/dist/transformation/utils/typescript/types.d.ts +2 -5
  50. package/dist/transformation/utils/typescript/types.js +27 -37
  51. package/dist/transformation/visitors/access.js +1 -4
  52. package/dist/transformation/visitors/block.js +4 -4
  53. package/dist/transformation/visitors/call.js +7 -18
  54. package/dist/transformation/visitors/class/index.js +8 -20
  55. package/dist/transformation/visitors/class/members/constructor.js +2 -2
  56. package/dist/transformation/visitors/class/new.js +2 -5
  57. package/dist/transformation/visitors/class/setup.d.ts +1 -1
  58. package/dist/transformation/visitors/class/setup.js +4 -4
  59. package/dist/transformation/visitors/class/utils.d.ts +1 -1
  60. package/dist/transformation/visitors/class/utils.js +2 -9
  61. package/dist/transformation/visitors/conditional.js +4 -4
  62. package/dist/transformation/visitors/function.d.ts +1 -1
  63. package/dist/transformation/visitors/function.js +8 -16
  64. package/dist/transformation/visitors/identifier.d.ts +1 -0
  65. package/dist/transformation/visitors/identifier.js +40 -44
  66. package/dist/transformation/visitors/language-extensions/call-extension.d.ts +10 -0
  67. package/dist/transformation/visitors/language-extensions/call-extension.js +23 -0
  68. package/dist/transformation/visitors/language-extensions/identifier.d.ts +5 -0
  69. package/dist/transformation/visitors/language-extensions/identifier.js +27 -0
  70. package/dist/transformation/visitors/language-extensions/iterable.d.ts +2 -3
  71. package/dist/transformation/visitors/language-extensions/iterable.js +21 -22
  72. package/dist/transformation/visitors/language-extensions/multi.d.ts +0 -1
  73. package/dist/transformation/visitors/language-extensions/multi.js +10 -24
  74. package/dist/transformation/visitors/language-extensions/operators.d.ts +2 -5
  75. package/dist/transformation/visitors/language-extensions/operators.js +89 -96
  76. package/dist/transformation/visitors/language-extensions/range.js +4 -2
  77. package/dist/transformation/visitors/language-extensions/table.d.ts +6 -3
  78. package/dist/transformation/visitors/language-extensions/table.js +46 -75
  79. package/dist/transformation/visitors/language-extensions/vararg.js +7 -3
  80. package/dist/transformation/visitors/literal.js +2 -23
  81. package/dist/transformation/visitors/loops/for-of.js +18 -18
  82. package/dist/transformation/visitors/loops/utils.js +5 -5
  83. package/dist/transformation/visitors/namespace.js +5 -14
  84. package/dist/transformation/visitors/return.js +2 -3
  85. package/dist/transformation/visitors/sourceFile.js +3 -4
  86. package/dist/transformation/visitors/spread.js +0 -5
  87. package/dist/transformation/visitors/switch.js +2 -2
  88. package/dist/transformation/visitors/variable-declaration.js +1 -1
  89. package/dist/transpilation/index.js +4 -8
  90. package/dist/transpilation/plugins.js +3 -0
  91. package/dist/transpilation/resolve.js +144 -161
  92. package/dist/transpilation/transpile.js +10 -0
  93. package/dist/transpilation/transpiler.d.ts +1 -0
  94. package/dist/transpilation/transpiler.js +18 -5
  95. package/dist/tstl.js +23 -4
  96. package/language-extensions/index.d.ts +167 -67
  97. package/package.json +2 -2
  98. package/dist/transformation/visitors/language-extensions/index.d.ts +0 -4
  99. package/dist/transformation/visitors/language-extensions/index.js +0 -17
  100. package/dist/transformation/visitors/language-extensions/pairsIterable.d.ts +0 -5
  101. package/dist/transformation/visitors/language-extensions/pairsIterable.js +0 -53
@@ -22,10 +22,10 @@ const diagnostics_1 = require("../utils/diagnostics");
22
22
  function transformBuiltinPropertyAccessExpression(context, node) {
23
23
  const ownerType = context.checker.getTypeAtLocation(node.expression);
24
24
  if (ts.isIdentifier(node.expression) && (0, typescript_1.isStandardLibraryType)(context, ownerType, undefined)) {
25
- switch (node.expression.text) {
25
+ switch (ownerType.symbol.name) {
26
26
  case "Math":
27
27
  return (0, math_1.transformMathProperty)(context, node);
28
- case "Symbol":
28
+ case "SymbolConstructor":
29
29
  (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Symbol);
30
30
  }
31
31
  }
@@ -40,102 +40,95 @@ function transformBuiltinPropertyAccessExpression(context, node) {
40
40
  }
41
41
  }
42
42
  exports.transformBuiltinPropertyAccessExpression = transformBuiltinPropertyAccessExpression;
43
- function transformBuiltinCallExpression(context, node, isOptionalCall) {
44
- const unsupportedOptionalCall = () => {
45
- context.diagnostics.push((0, diagnostics_1.unsupportedBuiltinOptionalCall)(node));
46
- return lua.createNilLiteral();
47
- };
43
+ function transformBuiltinCallExpression(context, node) {
48
44
  const expressionType = context.checker.getTypeAtLocation(node.expression);
49
45
  if (ts.isIdentifier(node.expression) && (0, typescript_1.isStandardLibraryType)(context, expressionType, undefined)) {
50
46
  checkForLuaLibType(context, expressionType);
51
- const result = (0, global_1.transformGlobalCall)(context, node);
52
- if (result) {
53
- if (isOptionalCall)
54
- return unsupportedOptionalCall();
47
+ const result = (0, global_1.tryTransformBuiltinGlobalCall)(context, node, expressionType);
48
+ if (result)
55
49
  return result;
56
- }
57
50
  }
58
51
  const calledMethod = ts.getOriginalNode((0, call_1.getCalledExpression)(node));
59
- if (!ts.isPropertyAccessExpression(calledMethod)) {
60
- return;
52
+ if (ts.isPropertyAccessExpression(calledMethod)) {
53
+ const globalResult = tryTransformBuiltinGlobalMethodCall(context, node, calledMethod);
54
+ if (globalResult)
55
+ return globalResult;
56
+ const prototypeResult = tryTransformBuiltinPropertyCall(context, node, calledMethod);
57
+ if (prototypeResult)
58
+ return prototypeResult;
59
+ // object prototype call may work even without resolved signature/type (which the other builtin calls use)
60
+ // e.g. (foo as any).toString()
61
+ // prototype methods take precedence (e.g. number.toString(2))
62
+ const objectResult = (0, object_1.tryTransformObjectPrototypeCall)(context, node, calledMethod);
63
+ if (objectResult)
64
+ return objectResult;
61
65
  }
62
- const isOptionalAccess = calledMethod.questionDotToken;
63
- // If the function being called is of type owner.func, get the type of owner
66
+ }
67
+ exports.transformBuiltinCallExpression = transformBuiltinCallExpression;
68
+ function tryTransformBuiltinGlobalMethodCall(context, node, calledMethod) {
64
69
  const ownerType = context.checker.getTypeAtLocation(calledMethod.expression);
65
- if ((0, typescript_1.isStandardLibraryType)(context, ownerType, undefined)) {
66
- const symbol = ownerType.getSymbol();
67
- switch (symbol === null || symbol === void 0 ? void 0 : symbol.name) {
68
- case "ArrayConstructor":
69
- if (isOptionalCall || isOptionalAccess)
70
- return unsupportedOptionalCall();
71
- return (0, array_1.transformArrayConstructorCall)(context, node, calledMethod);
72
- case "Console":
73
- if (isOptionalCall || isOptionalAccess)
74
- return unsupportedOptionalCall();
75
- return (0, console_1.transformConsoleCall)(context, node, calledMethod);
76
- case "Math":
77
- if (isOptionalCall || isOptionalAccess)
78
- return unsupportedOptionalCall();
79
- return (0, math_1.transformMathCall)(context, node, calledMethod);
80
- case "StringConstructor":
81
- if (isOptionalCall || isOptionalAccess)
82
- return unsupportedOptionalCall();
83
- return (0, string_1.transformStringConstructorCall)(context, node, calledMethod);
84
- case "ObjectConstructor":
85
- if (isOptionalCall || isOptionalAccess)
86
- return unsupportedOptionalCall();
87
- return (0, object_1.transformObjectConstructorCall)(context, node, calledMethod);
88
- case "SymbolConstructor":
89
- if (isOptionalCall || isOptionalAccess)
90
- return unsupportedOptionalCall();
91
- return (0, symbol_1.transformSymbolConstructorCall)(context, node, calledMethod);
92
- case "NumberConstructor":
93
- if (isOptionalCall || isOptionalAccess)
94
- return unsupportedOptionalCall();
95
- return (0, number_1.transformNumberConstructorCall)(context, node, calledMethod);
96
- case "PromiseConstructor":
97
- if (isOptionalCall || isOptionalAccess)
98
- return unsupportedOptionalCall();
99
- return (0, promise_1.transformPromiseConstructorCall)(context, node, calledMethod);
100
- }
101
- }
102
- const isStringFunction = (0, typescript_1.isStringType)(context, ownerType) ||
103
- (calledMethod.questionDotToken && (0, typescript_1.isNullableType)(context, ownerType, typescript_1.isStringType));
104
- if (isStringFunction && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
105
- if (isOptionalCall)
106
- return unsupportedOptionalCall();
107
- return (0, string_1.transformStringPrototypeCall)(context, node, calledMethod);
108
- }
109
- const isNumberFunction = (0, typescript_1.isNumberType)(context, ownerType) ||
110
- (calledMethod.questionDotToken && (0, typescript_1.isNullableType)(context, ownerType, typescript_1.isNumberType));
111
- if (isNumberFunction && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
112
- if (isOptionalCall)
113
- return unsupportedOptionalCall();
114
- return (0, number_1.transformNumberPrototypeCall)(context, node, calledMethod);
115
- }
116
- const isArrayFunction = (0, typescript_1.isArrayType)(context, ownerType) ||
117
- (calledMethod.questionDotToken && (0, typescript_1.isNullableType)(context, ownerType, typescript_1.isArrayType));
118
- if (isArrayFunction && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
119
- if (isOptionalCall)
120
- return unsupportedOptionalCall();
121
- return (0, array_1.transformArrayPrototypeCall)(context, node, calledMethod);
70
+ if (!(0, typescript_1.isStandardLibraryType)(context, ownerType, undefined))
71
+ return;
72
+ const ownerSymbol = ownerType.symbol;
73
+ if (!ownerSymbol || ownerSymbol.parent)
74
+ return;
75
+ let result;
76
+ switch (ownerSymbol.name) {
77
+ case "ArrayConstructor":
78
+ result = (0, array_1.transformArrayConstructorCall)(context, node, calledMethod);
79
+ break;
80
+ case "Console":
81
+ result = (0, console_1.transformConsoleCall)(context, node, calledMethod);
82
+ break;
83
+ case "Math":
84
+ result = (0, math_1.transformMathCall)(context, node, calledMethod);
85
+ break;
86
+ case "StringConstructor":
87
+ result = (0, string_1.transformStringConstructorCall)(context, node, calledMethod);
88
+ break;
89
+ case "ObjectConstructor":
90
+ result = (0, object_1.transformObjectConstructorCall)(context, node, calledMethod);
91
+ break;
92
+ case "SymbolConstructor":
93
+ result = (0, symbol_1.transformSymbolConstructorCall)(context, node, calledMethod);
94
+ break;
95
+ case "NumberConstructor":
96
+ result = (0, number_1.transformNumberConstructorCall)(context, node, calledMethod);
97
+ break;
98
+ case "PromiseConstructor":
99
+ result = (0, promise_1.transformPromiseConstructorCall)(context, node, calledMethod);
100
+ break;
122
101
  }
123
- const isFunctionFunction = (0, typescript_1.isFunctionType)(ownerType) ||
124
- (calledMethod.questionDotToken && (0, typescript_1.isNullableType)(context, ownerType, (_, t) => (0, typescript_1.isFunctionType)(t)));
125
- if (isFunctionFunction && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
126
- if (isOptionalCall)
127
- return unsupportedOptionalCall();
128
- return (0, function_1.transformFunctionPrototypeCall)(context, node, calledMethod);
102
+ if (result && calledMethod.questionDotToken) {
103
+ // e.g. console?.log()
104
+ context.diagnostics.push((0, diagnostics_1.unsupportedBuiltinOptionalCall)(calledMethod));
129
105
  }
130
- const objectResult = (0, object_1.transformObjectPrototypeCall)(context, node, calledMethod);
131
- if (objectResult) {
132
- if (isOptionalCall)
133
- return unsupportedOptionalCall();
134
- return objectResult;
106
+ return result;
107
+ }
108
+ function tryTransformBuiltinPropertyCall(context, node, calledMethod) {
109
+ var _a;
110
+ const signatureDeclaration = (_a = context.checker.getResolvedSignature(node)) === null || _a === void 0 ? void 0 : _a.declaration;
111
+ if (!signatureDeclaration || !(0, typescript_1.isStandardLibraryDeclaration)(context, signatureDeclaration))
112
+ return;
113
+ const callSymbol = context.checker.getTypeAtLocation(signatureDeclaration).symbol;
114
+ const ownerSymbol = callSymbol.parent;
115
+ if (!ownerSymbol || ownerSymbol.parent)
116
+ return;
117
+ switch (ownerSymbol.name) {
118
+ case "String":
119
+ return (0, string_1.transformStringPrototypeCall)(context, node, calledMethod);
120
+ case "Number":
121
+ return (0, number_1.transformNumberPrototypeCall)(context, node, calledMethod);
122
+ case "Array":
123
+ case "ReadonlyArray":
124
+ return (0, array_1.transformArrayPrototypeCall)(context, node, calledMethod);
125
+ case "Function":
126
+ case "CallableFunction":
127
+ case "NewableFunction":
128
+ return (0, function_1.transformFunctionPrototypeCall)(context, node, calledMethod);
135
129
  }
136
130
  }
137
- exports.transformBuiltinCallExpression = transformBuiltinCallExpression;
138
- function transformBuiltinIdentifierExpression(context, node) {
131
+ function transformBuiltinIdentifierExpression(context, node, symbol) {
139
132
  switch (node.text) {
140
133
  case "NaN":
141
134
  return (0, lua_ast_1.createNaN)(node);
@@ -144,7 +137,7 @@ function transformBuiltinIdentifierExpression(context, node) {
144
137
  const huge = lua.createStringLiteral("huge");
145
138
  return lua.createTableIndexExpression(math, huge, node);
146
139
  case "globalThis":
147
- return lua.createIdentifier("_G", node, (0, symbols_1.getIdentifierSymbolId)(context, node), "globalThis");
140
+ return lua.createIdentifier("_G", node, (0, symbols_1.getIdentifierSymbolId)(context, node, symbol), "globalThis");
148
141
  }
149
142
  }
150
143
  exports.transformBuiltinIdentifierExpression = transformBuiltinIdentifierExpression;
@@ -163,9 +156,10 @@ const builtinErrorTypeNames = new Set([
163
156
  "URIErrorConstructor",
164
157
  ]);
165
158
  function checkForLuaLibType(context, type) {
166
- if (!type.symbol)
159
+ const symbol = type.symbol;
160
+ if (!symbol || symbol.parent)
167
161
  return;
168
- const name = context.checker.getFullyQualifiedName(type.symbol);
162
+ const name = symbol.name;
169
163
  switch (name) {
170
164
  case "Map":
171
165
  case "MapConstructor":
@@ -183,6 +177,10 @@ function checkForLuaLibType(context, type) {
183
177
  case "WeakSetConstructor":
184
178
  (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.WeakSet);
185
179
  return;
180
+ case "Promise":
181
+ case "PromiseConstructor":
182
+ (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Promise);
183
+ return;
186
184
  }
187
185
  if (builtinErrorTypeNames.has(name)) {
188
186
  (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Error);
@@ -2,4 +2,4 @@ import * as lua from "../../LuaAST";
2
2
  import * as ts from "typescript";
3
3
  import { TransformationContext } from "../context";
4
4
  export declare function transformObjectConstructorCall(context: TransformationContext, node: ts.CallExpression, calledMethod: ts.PropertyAccessExpression): lua.Expression | undefined;
5
- export declare function transformObjectPrototypeCall(context: TransformationContext, node: ts.CallExpression, calledMethod: ts.PropertyAccessExpression): lua.Expression | undefined;
5
+ export declare function tryTransformObjectPrototypeCall(context: TransformationContext, node: ts.CallExpression, calledMethod: ts.PropertyAccessExpression): lua.Expression | undefined;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformObjectPrototypeCall = exports.transformObjectConstructorCall = void 0;
3
+ exports.tryTransformObjectPrototypeCall = exports.transformObjectConstructorCall = void 0;
4
4
  const lua = require("../../LuaAST");
5
5
  const diagnostics_1 = require("../utils/diagnostics");
6
6
  const lualib_1 = require("../utils/lualib");
@@ -30,8 +30,7 @@ function transformObjectConstructorCall(context, node, calledMethod) {
30
30
  }
31
31
  }
32
32
  exports.transformObjectConstructorCall = transformObjectConstructorCall;
33
- function transformObjectPrototypeCall(context, node, calledMethod) {
34
- const signature = context.checker.getResolvedSignature(node);
33
+ function tryTransformObjectPrototypeCall(context, node, calledMethod) {
35
34
  const name = calledMethod.name.text;
36
35
  switch (name) {
37
36
  case "toString":
@@ -39,11 +38,12 @@ function transformObjectPrototypeCall(context, node, calledMethod) {
39
38
  return lua.createCallExpression(toStringIdentifier, [context.transformExpression(calledMethod.expression)], node);
40
39
  case "hasOwnProperty":
41
40
  const expr = context.transformExpression(calledMethod.expression);
41
+ const signature = context.checker.getResolvedSignature(node);
42
42
  const parameters = (0, call_1.transformArguments)(context, node.arguments, signature);
43
43
  const rawGetIdentifier = lua.createIdentifier("rawget");
44
44
  const rawGetCall = lua.createCallExpression(rawGetIdentifier, [expr, ...parameters]);
45
45
  return lua.createBinaryExpression(rawGetCall, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator, node);
46
46
  }
47
47
  }
48
- exports.transformObjectPrototypeCall = transformObjectPrototypeCall;
48
+ exports.tryTransformObjectPrototypeCall = tryTransformObjectPrototypeCall;
49
49
  //# sourceMappingURL=object.js.map
@@ -4,11 +4,13 @@ exports.createStaticPromiseFunctionAccessor = exports.transformPromiseConstructo
4
4
  const lua = require("../../LuaAST");
5
5
  const diagnostics_1 = require("../utils/diagnostics");
6
6
  const lualib_1 = require("../utils/lualib");
7
- const typescript_1 = require("../utils/typescript");
8
7
  const call_1 = require("../visitors/call");
8
+ const typescript_1 = require("../utils/typescript");
9
9
  function isPromiseClass(context, node) {
10
+ if (node.text !== "Promise")
11
+ return false;
10
12
  const type = context.checker.getTypeAtLocation(node);
11
- return (0, typescript_1.isStandardLibraryType)(context, type, undefined) && node.text === "Promise";
13
+ return (0, typescript_1.isStandardLibraryType)(context, type, undefined);
12
14
  }
13
15
  exports.isPromiseClass = isPromiseClass;
14
16
  function createPromiseIdentifier(original) {
@@ -100,6 +100,8 @@ function transformStringPrototypeCall(context, node, calledMethod) {
100
100
  return (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.StringPadStart, node, caller, ...params);
101
101
  case "padEnd":
102
102
  return (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.StringPadEnd, node, caller, ...params);
103
+ case "toString":
104
+ return; // will be handled by transformObjectPrototypeCall
103
105
  default:
104
106
  context.diagnostics.push((0, diagnostics_1.unsupportedProperty)(calledMethod.name, "string", expressionName));
105
107
  }
@@ -2,6 +2,9 @@ import * as ts from "typescript";
2
2
  import { CompilerOptions, LuaTarget } from "../../CompilerOptions";
3
3
  import * as lua from "../../LuaAST";
4
4
  import { ExpressionLikeNode, StatementLikeNode, VisitorMap } from "./visitors";
5
+ import { SymbolInfo } from "../utils/symbols";
6
+ import { LuaLibFeature } from "../../LuaLib";
7
+ import { Scope, ScopeType } from "../utils/scope";
5
8
  export declare const tempSymbolId: lua.SymbolId;
6
9
  export interface AllAccessorDeclarations {
7
10
  firstAccessor: ts.AccessorDeclaration;
@@ -33,10 +36,13 @@ export declare class TransformationContext {
33
36
  readonly isStrict: boolean;
34
37
  constructor(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap);
35
38
  private currentNodeVisitors;
39
+ private currentNodeVisitorsIndex;
36
40
  private nextTempId;
37
41
  transformNode(node: ts.Node): lua.Node[];
38
42
  superTransformNode(node: ts.Node): lua.Node[];
43
+ private doSuperTransformNode;
39
44
  transformExpression(node: ExpressionLikeNode): lua.Expression;
45
+ private assertIsExpression;
40
46
  superTransformExpression(node: ExpressionLikeNode): lua.Expression;
41
47
  transformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[];
42
48
  superTransformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[];
@@ -49,4 +55,13 @@ export declare class TransformationContext {
49
55
  createTempNameForLuaExpression(expression: lua.Expression): lua.Identifier;
50
56
  private getTempNameForNode;
51
57
  createTempNameForNode(node: ts.Node): lua.Identifier;
58
+ private lastSymbolId;
59
+ readonly symbolInfoMap: Map<lua.SymbolId, SymbolInfo>;
60
+ readonly symbolIdMaps: Map<ts.Symbol, lua.SymbolId>;
61
+ nextSymbolId(): lua.SymbolId;
62
+ readonly usedLuaLibFeatures: Set<LuaLibFeature>;
63
+ readonly scopeStack: Scope[];
64
+ private lastScopeId;
65
+ pushScope(type: ScopeType): Scope;
66
+ popScope(): Scope;
52
67
  }
@@ -24,66 +24,91 @@ class TransformationContext {
24
24
  this.isStrict = ((_b = this.options.alwaysStrict) !== null && _b !== void 0 ? _b : this.options.strict) ||
25
25
  (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015);
26
26
  this.currentNodeVisitors = [];
27
+ this.currentNodeVisitorsIndex = 0;
27
28
  this.nextTempId = 0;
29
+ // other utils
30
+ this.lastSymbolId = 0;
31
+ this.symbolInfoMap = new Map();
32
+ this.symbolIdMaps = new Map();
33
+ this.usedLuaLibFeatures = new Set();
34
+ this.scopeStack = [];
35
+ this.lastScopeId = 0;
36
+ /** @internal */
37
+ this.classSuperInfos = [];
28
38
  // Use `getParseTreeNode` to get original SourceFile node, before it was substituted by custom transformers.
29
39
  // It's required because otherwise `getEmitResolver` won't use cached diagnostics, produced in `emitWorker`
30
40
  // and would try to re-analyze the file, which would fail because of replaced nodes.
31
41
  const originalSourceFile = (_c = ts.getParseTreeNode(sourceFile, ts.isSourceFile)) !== null && _c !== void 0 ? _c : sourceFile;
32
42
  this.resolver = this.checker.getEmitResolver(originalSourceFile);
33
43
  }
34
- transformNode(node, isExpression) {
44
+ transformNode(node) {
45
+ return (0, lua_ast_1.unwrapVisitorResult)(this.transformNodeRaw(node));
46
+ }
47
+ /** @internal */
48
+ transformNodeRaw(node, isExpression) {
35
49
  var _a;
36
50
  // TODO: Move to visitors?
37
51
  if ((_a = node.modifiers) === null || _a === void 0 ? void 0 : _a.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) {
38
52
  return [];
39
53
  }
40
54
  const nodeVisitors = this.visitorMap.get(node.kind);
41
- if (!nodeVisitors || nodeVisitors.length === 0) {
55
+ if (!nodeVisitors) {
42
56
  this.diagnostics.push((0, diagnostics_1.unsupportedNodeKind)(node, node.kind));
43
57
  return isExpression ? [lua.createNilLiteral()] : [];
44
58
  }
45
59
  const previousNodeVisitors = this.currentNodeVisitors;
46
- this.currentNodeVisitors = [...nodeVisitors];
47
- const visitor = this.currentNodeVisitors.pop();
48
- const result = (0, lua_ast_1.unwrapVisitorResult)(visitor.transform(node, this));
60
+ const previousNodeVisitorsIndex = this.currentNodeVisitorsIndex;
61
+ this.currentNodeVisitors = nodeVisitors;
62
+ this.currentNodeVisitorsIndex = nodeVisitors.length - 1;
63
+ const visitor = this.currentNodeVisitors[this.currentNodeVisitorsIndex];
64
+ const result = visitor(node, this);
49
65
  this.currentNodeVisitors = previousNodeVisitors;
66
+ this.currentNodeVisitorsIndex = previousNodeVisitorsIndex;
50
67
  return result;
51
68
  }
52
69
  superTransformNode(node) {
53
- if (this.currentNodeVisitors.length === 0) {
70
+ return (0, lua_ast_1.unwrapVisitorResult)(this.doSuperTransformNode(node));
71
+ }
72
+ doSuperTransformNode(node) {
73
+ if (--this.currentNodeVisitorsIndex < 0) {
54
74
  throw new Error(`There is no super transform for ${ts.SyntaxKind[node.kind]} visitor`);
55
75
  }
56
- const visitor = this.currentNodeVisitors.pop();
57
- return (0, lua_ast_1.unwrapVisitorResult)(visitor.transform(node, this));
76
+ const visitor = this.currentNodeVisitors[this.currentNodeVisitorsIndex];
77
+ return (0, lua_ast_1.unwrapVisitorResult)(visitor(node, this));
58
78
  }
59
79
  transformExpression(node) {
60
- const [result] = this.transformNode(node, true);
80
+ const result = this.transformNodeRaw(node, true);
81
+ return this.assertIsExpression(node, result);
82
+ }
83
+ assertIsExpression(node, result) {
61
84
  if (result === undefined) {
62
85
  throw new Error(`Expression visitor for node type ${ts.SyntaxKind[node.kind]} did not return any result.`);
63
86
  }
87
+ if (Array.isArray(result)) {
88
+ return result[0];
89
+ }
64
90
  return result;
65
91
  }
66
92
  superTransformExpression(node) {
67
- const [result] = this.superTransformNode(node);
68
- if (result === undefined) {
69
- throw new Error(`Expression visitor for node type ${ts.SyntaxKind[node.kind]} did not return any result.`);
70
- }
71
- return result;
93
+ const result = this.doSuperTransformNode(node);
94
+ return this.assertIsExpression(node, result);
72
95
  }
73
96
  transformStatements(node) {
74
97
  return (0, utils_1.castArray)(node).flatMap(n => {
75
98
  this.pushPrecedingStatements();
76
99
  const statements = this.transformNode(n);
77
- statements.unshift(...this.popPrecedingStatements());
78
- return statements;
100
+ const result = this.popPrecedingStatements();
101
+ result.push(...statements);
102
+ return result;
79
103
  });
80
104
  }
81
105
  superTransformStatements(node) {
82
106
  return (0, utils_1.castArray)(node).flatMap(n => {
83
107
  this.pushPrecedingStatements();
84
108
  const statements = this.superTransformNode(n);
85
- statements.unshift(...this.popPrecedingStatements());
86
- return statements;
109
+ const result = this.popPrecedingStatements();
110
+ result.push(...statements);
111
+ return result;
87
112
  });
88
113
  }
89
114
  pushPrecedingStatements() {
@@ -97,18 +122,22 @@ class TransformationContext {
97
122
  addPrecedingStatements(statements) {
98
123
  const precedingStatements = this.precedingStatementsStack[this.precedingStatementsStack.length - 1];
99
124
  (0, utils_1.assert)(precedingStatements);
100
- if (!Array.isArray(statements)) {
101
- statements = [statements];
125
+ if (Array.isArray(statements)) {
126
+ precedingStatements.push(...statements);
127
+ }
128
+ else {
129
+ precedingStatements.push(statements);
102
130
  }
103
- precedingStatements.push(...statements);
104
131
  }
105
132
  prependPrecedingStatements(statements) {
106
133
  const precedingStatements = this.precedingStatementsStack[this.precedingStatementsStack.length - 1];
107
134
  (0, utils_1.assert)(precedingStatements);
108
- if (!Array.isArray(statements)) {
109
- statements = [statements];
135
+ if (Array.isArray(statements)) {
136
+ precedingStatements.unshift(...statements);
137
+ }
138
+ else {
139
+ precedingStatements.unshift(statements);
110
140
  }
111
- precedingStatements.unshift(...statements);
112
141
  }
113
142
  createTempName(prefix = "temp") {
114
143
  prefix = prefix.replace(/^_*/, ""); // Strip leading underscores because createSafeName will add them again
@@ -171,6 +200,19 @@ class TransformationContext {
171
200
  const name = this.getTempNameForNode(node);
172
201
  return lua.createIdentifier(this.createTempName(name), node, exports.tempSymbolId);
173
202
  }
203
+ nextSymbolId() {
204
+ return ++this.lastSymbolId;
205
+ }
206
+ pushScope(type) {
207
+ const scope = { type, id: ++this.lastScopeId };
208
+ this.scopeStack.push(scope);
209
+ return scope;
210
+ }
211
+ popScope() {
212
+ const scope = this.scopeStack.pop();
213
+ (0, utils_1.assert)(scope);
214
+ return scope;
215
+ }
174
216
  }
175
217
  exports.TransformationContext = TransformationContext;
176
218
  //# sourceMappingURL=context.js.map
@@ -149,5 +149,5 @@ export interface ObjectVisitor<T extends ts.Node> {
149
149
  export declare type Visitors = {
150
150
  [P in keyof NodesBySyntaxKind]?: Visitor<NodesBySyntaxKind[P]>;
151
151
  };
152
- export declare type VisitorMap = Map<ts.SyntaxKind, Array<ObjectVisitor<ts.Node>>>;
152
+ export declare type VisitorMap = Map<ts.SyntaxKind, Array<FunctionVisitor<ts.Node>>>;
153
153
  export {};
@@ -5,22 +5,23 @@ const utils_1 = require("../utils");
5
5
  const context_1 = require("./context");
6
6
  const visitors_1 = require("./visitors");
7
7
  function createVisitorMap(customVisitors) {
8
- const visitorMap = new Map();
8
+ const objectVisitorMap = new Map();
9
9
  for (const visitors of [visitors_1.standardVisitors, ...customVisitors]) {
10
10
  const priority = visitors === visitors_1.standardVisitors ? -Infinity : 0;
11
11
  for (const [syntaxKindKey, visitor] of Object.entries(visitors)) {
12
12
  if (!visitor)
13
13
  continue;
14
14
  const syntaxKind = Number(syntaxKindKey);
15
- const nodeVisitors = (0, utils_1.getOrUpdate)(visitorMap, syntaxKind, () => []);
15
+ const nodeVisitors = (0, utils_1.getOrUpdate)(objectVisitorMap, syntaxKind, () => []);
16
16
  const objectVisitor = typeof visitor === "function" ? { transform: visitor, priority } : visitor;
17
17
  nodeVisitors.push(objectVisitor);
18
18
  }
19
19
  }
20
- for (const nodeVisitors of visitorMap.values()) {
21
- nodeVisitors.sort((a, b) => { var _a, _b; return ((_a = a.priority) !== null && _a !== void 0 ? _a : 0) - ((_b = b.priority) !== null && _b !== void 0 ? _b : 0); });
20
+ const result = new Map();
21
+ for (const [kind, nodeVisitors] of objectVisitorMap) {
22
+ result.set(kind, nodeVisitors.sort((a, b) => { var _a, _b; return ((_a = a.priority) !== null && _a !== void 0 ? _a : 0) - ((_b = b.priority) !== null && _b !== void 0 ? _b : 0); }).map(visitor => visitor.transform));
22
23
  }
23
- return visitorMap;
24
+ return result;
24
25
  }
25
26
  exports.createVisitorMap = createVisitorMap;
26
27
  function transformSourceFile(program, sourceFile, visitorMap) {
@@ -1,20 +1,10 @@
1
1
  import * as ts from "typescript";
2
- import { TransformationContext } from "../context";
3
2
  export declare enum AnnotationKind {
4
- Extension = "extension",
5
- MetaExtension = "metaExtension",
6
3
  CustomConstructor = "customConstructor",
7
4
  CompileMembersOnly = "compileMembersOnly",
8
5
  NoResolution = "noResolution",
9
- PureAbstract = "pureAbstract",
10
- Phantom = "phantom",
11
- TupleReturn = "tupleReturn",
12
- LuaIterator = "luaIterator",
13
- LuaTable = "luaTable",
14
6
  NoSelf = "noSelf",
15
- NoSelfInFile = "noSelfInFile",
16
- Vararg = "vararg",
17
- ForRange = "forRange"
7
+ NoSelfInFile = "noSelfInFile"
18
8
  }
19
9
  export interface Annotation {
20
10
  kind: AnnotationKind;
@@ -25,9 +15,3 @@ export declare function getSymbolAnnotations(symbol: ts.Symbol): AnnotationsMap;
25
15
  export declare function getTypeAnnotations(type: ts.Type): AnnotationsMap;
26
16
  export declare function getNodeAnnotations(node: ts.Node): AnnotationsMap;
27
17
  export declare function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap;
28
- export declare function getSignatureAnnotations(context: TransformationContext, signature: ts.Signature): AnnotationsMap;
29
- export declare function isTupleReturnCall(context: TransformationContext, node: ts.Node): boolean;
30
- export declare function isLuaIteratorType(context: TransformationContext, node: ts.Node): boolean;
31
- export declare function isVarargType(context: TransformationContext, node: ts.Node): boolean;
32
- export declare function isForRangeType(context: TransformationContext, node: ts.Node): boolean;
33
- export declare function getTagArgsFromComment(tag: ts.JSDocTag): string[];