typescript-to-lua 1.6.3 → 1.7.2

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 (98) hide show
  1. package/dist/CompilerOptions.d.ts +1 -0
  2. package/dist/cli/parse.js +5 -0
  3. package/dist/lualib/ArraySlice.lua +10 -2
  4. package/dist/lualib/ArraySplice.lua +5 -1
  5. package/dist/lualib/Generator.lua +8 -1
  6. package/dist/lualib/ParseFloat.lua +5 -1
  7. package/dist/lualib/SparseArraySpread.lua +5 -1
  8. package/dist/lualib/StringCharCodeAt.lua +5 -1
  9. package/dist/lualib/lualib_bundle.lua +38 -7
  10. package/dist/lualib-build/plugin.js +1 -2
  11. package/dist/measure-performance.d.ts +15 -0
  12. package/dist/measure-performance.js +83 -0
  13. package/dist/transformation/builtins/array.js +2 -1
  14. package/dist/transformation/builtins/function.js +1 -1
  15. package/dist/transformation/builtins/global.d.ts +1 -1
  16. package/dist/transformation/builtins/global.js +13 -12
  17. package/dist/transformation/builtins/index.d.ts +2 -2
  18. package/dist/transformation/builtins/index.js +87 -89
  19. package/dist/transformation/builtins/object.d.ts +1 -1
  20. package/dist/transformation/builtins/object.js +4 -4
  21. package/dist/transformation/builtins/promise.js +4 -2
  22. package/dist/transformation/builtins/string.js +2 -0
  23. package/dist/transformation/context/context.d.ts +15 -0
  24. package/dist/transformation/context/context.js +66 -24
  25. package/dist/transformation/context/visitors.d.ts +1 -1
  26. package/dist/transformation/index.js +6 -5
  27. package/dist/transformation/utils/annotations.d.ts +1 -17
  28. package/dist/transformation/utils/annotations.js +48 -88
  29. package/dist/transformation/utils/assignment-validation.js +27 -23
  30. package/dist/transformation/utils/diagnostics.d.ts +1 -4
  31. package/dist/transformation/utils/diagnostics.js +2 -3
  32. package/dist/transformation/utils/function-context.d.ts +1 -1
  33. package/dist/transformation/utils/function-context.js +57 -51
  34. package/dist/transformation/utils/language-extensions.d.ts +57 -51
  35. package/dist/transformation/utils/language-extensions.js +99 -119
  36. package/dist/transformation/utils/lualib.d.ts +0 -1
  37. package/dist/transformation/utils/lualib.js +2 -8
  38. package/dist/transformation/utils/safe-names.d.ts +1 -1
  39. package/dist/transformation/utils/safe-names.js +3 -6
  40. package/dist/transformation/utils/scope.d.ts +0 -2
  41. package/dist/transformation/utils/scope.js +10 -27
  42. package/dist/transformation/utils/symbols.d.ts +1 -1
  43. package/dist/transformation/utils/symbols.js +7 -20
  44. package/dist/transformation/utils/typescript/index.d.ts +1 -0
  45. package/dist/transformation/utils/typescript/index.js +2 -1
  46. package/dist/transformation/utils/typescript/types.d.ts +2 -5
  47. package/dist/transformation/utils/typescript/types.js +27 -37
  48. package/dist/transformation/visitors/access.js +1 -4
  49. package/dist/transformation/visitors/block.js +4 -4
  50. package/dist/transformation/visitors/call.js +10 -21
  51. package/dist/transformation/visitors/class/index.js +8 -20
  52. package/dist/transformation/visitors/class/members/constructor.js +2 -2
  53. package/dist/transformation/visitors/class/new.js +2 -5
  54. package/dist/transformation/visitors/class/setup.d.ts +1 -1
  55. package/dist/transformation/visitors/class/setup.js +4 -4
  56. package/dist/transformation/visitors/class/utils.d.ts +1 -1
  57. package/dist/transformation/visitors/class/utils.js +2 -9
  58. package/dist/transformation/visitors/conditional.js +4 -4
  59. package/dist/transformation/visitors/function.d.ts +1 -1
  60. package/dist/transformation/visitors/function.js +8 -16
  61. package/dist/transformation/visitors/identifier.d.ts +1 -0
  62. package/dist/transformation/visitors/identifier.js +40 -44
  63. package/dist/transformation/visitors/language-extensions/call-extension.d.ts +10 -0
  64. package/dist/transformation/visitors/language-extensions/call-extension.js +23 -0
  65. package/dist/transformation/visitors/language-extensions/identifier.d.ts +5 -0
  66. package/dist/transformation/visitors/language-extensions/identifier.js +27 -0
  67. package/dist/transformation/visitors/language-extensions/iterable.d.ts +2 -3
  68. package/dist/transformation/visitors/language-extensions/iterable.js +23 -22
  69. package/dist/transformation/visitors/language-extensions/multi.d.ts +0 -1
  70. package/dist/transformation/visitors/language-extensions/multi.js +10 -24
  71. package/dist/transformation/visitors/language-extensions/operators.d.ts +2 -5
  72. package/dist/transformation/visitors/language-extensions/operators.js +89 -96
  73. package/dist/transformation/visitors/language-extensions/range.js +4 -2
  74. package/dist/transformation/visitors/language-extensions/table.d.ts +6 -3
  75. package/dist/transformation/visitors/language-extensions/table.js +46 -75
  76. package/dist/transformation/visitors/language-extensions/vararg.js +7 -3
  77. package/dist/transformation/visitors/literal.js +2 -23
  78. package/dist/transformation/visitors/loops/for-of.js +18 -18
  79. package/dist/transformation/visitors/loops/utils.js +5 -5
  80. package/dist/transformation/visitors/modules/import.js +2 -2
  81. package/dist/transformation/visitors/namespace.js +5 -14
  82. package/dist/transformation/visitors/return.js +2 -3
  83. package/dist/transformation/visitors/sourceFile.js +3 -4
  84. package/dist/transformation/visitors/spread.js +0 -5
  85. package/dist/transformation/visitors/switch.js +2 -2
  86. package/dist/transformation/visitors/variable-declaration.js +1 -1
  87. package/dist/transpilation/plugins.js +3 -0
  88. package/dist/transpilation/resolve.js +210 -186
  89. package/dist/transpilation/transpile.js +10 -0
  90. package/dist/transpilation/transpiler.d.ts +1 -0
  91. package/dist/transpilation/transpiler.js +18 -5
  92. package/dist/tstl.js +21 -0
  93. package/language-extensions/index.d.ts +167 -67
  94. package/package.json +2 -2
  95. package/dist/transformation/visitors/language-extensions/index.d.ts +0 -4
  96. package/dist/transformation/visitors/language-extensions/index.js +0 -17
  97. package/dist/transformation/visitors/language-extensions/pairsIterable.d.ts +0 -5
  98. package/dist/transformation/visitors/language-extensions/pairsIterable.js +0 -53
@@ -2,8 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getExtendedType = exports.getExtendedNode = exports.getExtendsClause = exports.isStaticNode = void 0;
4
4
  const ts = require("typescript");
5
- const annotations_1 = require("../../utils/annotations");
6
- const diagnostics_1 = require("../../utils/diagnostics");
7
5
  function isStaticNode(node) {
8
6
  var _a;
9
7
  return ((_a = node.modifiers) !== null && _a !== void 0 ? _a : []).some(m => m.kind === ts.SyntaxKind.StaticKeyword);
@@ -14,20 +12,15 @@ function getExtendsClause(node) {
14
12
  return ((_a = node.heritageClauses) !== null && _a !== void 0 ? _a : []).find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword);
15
13
  }
16
14
  exports.getExtendsClause = getExtendsClause;
17
- function getExtendedNode(context, node) {
15
+ function getExtendedNode(node) {
18
16
  const extendsClause = getExtendsClause(node);
19
17
  if (!extendsClause)
20
18
  return;
21
- const superType = context.checker.getTypeAtLocation(extendsClause.types[0]);
22
- const annotations = (0, annotations_1.getTypeAnnotations)(superType);
23
- if (annotations.has(annotations_1.AnnotationKind.PureAbstract)) {
24
- context.diagnostics.push((0, diagnostics_1.annotationRemoved)(extendsClause, annotations_1.AnnotationKind.PureAbstract));
25
- }
26
19
  return extendsClause.types[0];
27
20
  }
28
21
  exports.getExtendedNode = getExtendedNode;
29
22
  function getExtendedType(context, node) {
30
- const extendedNode = getExtendedNode(context, node);
23
+ const extendedNode = getExtendedNode(node);
31
24
  return extendedNode && context.checker.getTypeAtLocation(extendedNode);
32
25
  }
33
26
  exports.getExtendedType = getExtendedType;
@@ -34,10 +34,10 @@ const transformConditionalExpression = (expression, context) => {
34
34
  };
35
35
  exports.transformConditionalExpression = transformConditionalExpression;
36
36
  function transformIfStatement(statement, context) {
37
- (0, scope_1.pushScope)(context, scope_1.ScopeType.Conditional);
37
+ context.pushScope(scope_1.ScopeType.Conditional);
38
38
  const condition = context.transformExpression(statement.expression);
39
39
  const statements = (0, scope_1.performHoisting)(context, (0, block_1.transformBlockOrStatement)(context, statement.thenStatement));
40
- (0, scope_1.popScope)(context);
40
+ context.popScope();
41
41
  const ifBlock = lua.createBlock(statements);
42
42
  if (statement.elseStatement) {
43
43
  if (ts.isIfStatement(statement.elseStatement)) {
@@ -60,9 +60,9 @@ function transformIfStatement(statement, context) {
60
60
  }
61
61
  }
62
62
  else {
63
- (0, scope_1.pushScope)(context, scope_1.ScopeType.Conditional);
63
+ context.pushScope(scope_1.ScopeType.Conditional);
64
64
  const elseStatements = (0, scope_1.performHoisting)(context, (0, block_1.transformBlockOrStatement)(context, statement.elseStatement));
65
- (0, scope_1.popScope)(context);
65
+ context.popScope();
66
66
  const elseBlock = lua.createBlock(elseStatements);
67
67
  return lua.createIfStatement(condition, ifBlock, elseBlock);
68
68
  }
@@ -3,7 +3,7 @@ import * as lua from "../../LuaAST";
3
3
  import { FunctionVisitor, TransformationContext } from "../context";
4
4
  import { Scope } from "../utils/scope";
5
5
  export declare function createCallableTable(functionExpression: lua.Expression): lua.Expression;
6
- export declare function isFunctionTypeWithProperties(functionType: ts.Type): boolean;
6
+ export declare function isFunctionTypeWithProperties(context: TransformationContext, functionType: ts.Type): boolean;
7
7
  export declare function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[];
8
8
  export declare function transformFunctionBodyHeader(context: TransformationContext, bodyScope: Scope, parameters: ts.NodeArray<ts.ParameterDeclaration>, spreadIdentifier?: lua.Identifier): lua.Statement[];
9
9
  export declare function transformFunctionBody(context: TransformationContext, parameters: ts.NodeArray<ts.ParameterDeclaration>, body: ts.ConciseBody, spreadIdentifier?: lua.Identifier, node?: ts.FunctionLikeDeclaration): [lua.Statement[], Scope];
@@ -4,8 +4,6 @@ exports.transformYieldExpression = exports.transformFunctionDeclaration = export
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../LuaAST");
6
6
  const utils_1 = require("../../utils");
7
- const annotations_1 = require("../utils/annotations");
8
- const diagnostics_1 = require("../utils/diagnostics");
9
7
  const export_1 = require("../utils/export");
10
8
  const function_context_1 = require("../utils/function-context");
11
9
  const language_extensions_1 = require("../utils/language-extensions");
@@ -56,14 +54,14 @@ function createCallableTable(functionExpression) {
56
54
  ]);
57
55
  }
58
56
  exports.createCallableTable = createCallableTable;
59
- function isFunctionTypeWithProperties(functionType) {
57
+ function isFunctionTypeWithProperties(context, functionType) {
60
58
  if (functionType.isUnion()) {
61
- return functionType.types.some(isFunctionTypeWithProperties);
59
+ return functionType.types.some(t => isFunctionTypeWithProperties(context, t));
62
60
  }
63
61
  else {
64
62
  return ((0, typescript_1.isFunctionType)(functionType) &&
65
63
  functionType.getProperties().length > 0 &&
66
- (0, language_extensions_1.getExtensionKinds)(functionType).length === 0 // ignore TSTL extension functions like $range
64
+ (0, language_extensions_1.getExtensionKindForType)(context, functionType) === undefined // ignore TSTL extension functions like $range
67
65
  );
68
66
  }
69
67
  }
@@ -110,14 +108,14 @@ function transformFunctionBodyHeader(context, bodyScope, parameters, spreadIdent
110
108
  }
111
109
  exports.transformFunctionBodyHeader = transformFunctionBodyHeader;
112
110
  function transformFunctionBody(context, parameters, body, spreadIdentifier, node) {
113
- const scope = (0, scope_1.pushScope)(context, scope_1.ScopeType.Function);
111
+ const scope = context.pushScope(scope_1.ScopeType.Function);
114
112
  scope.node = node;
115
113
  let bodyStatements = transformFunctionBodyContent(context, body);
116
114
  if (node && (0, async_await_1.isAsyncFunction)(node)) {
117
115
  bodyStatements = [lua.createReturnStatement([(0, async_await_1.wrapInAsyncAwaiter)(context, bodyStatements)])];
118
116
  }
119
117
  const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier);
120
- (0, scope_1.popScope)(context);
118
+ context.popScope();
121
119
  return [[...headerStatements, ...bodyStatements], scope];
122
120
  }
123
121
  exports.transformFunctionBody = transformFunctionBody;
@@ -191,9 +189,6 @@ function transformFunctionLikeDeclaration(node, context) {
191
189
  // This code can be reached only from object methods, which is TypeScript error
192
190
  return lua.createNilLiteral();
193
191
  }
194
- if ((0, annotations_1.getNodeAnnotations)(node).has(annotations_1.AnnotationKind.TupleReturn)) {
195
- context.diagnostics.push((0, diagnostics_1.annotationRemoved)(node, annotations_1.AnnotationKind.TupleReturn));
196
- }
197
192
  const [functionExpression, functionScope] = transformFunctionToExpression(context, node);
198
193
  const isNamedFunctionExpression = ts.isFunctionExpression(node) && node.name;
199
194
  // Handle named function expressions which reference themselves
@@ -205,7 +200,7 @@ function transformFunctionLikeDeclaration(node, context) {
205
200
  // Only handle if the name is actually referenced inside the function
206
201
  if (isReferenced) {
207
202
  const nameIdentifier = (0, identifier_1.transformIdentifier)(context, node.name);
208
- if (isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node))) {
203
+ if (isFunctionTypeWithProperties(context, context.checker.getTypeAtLocation(node))) {
209
204
  context.addPrecedingStatements([
210
205
  lua.createVariableDeclarationStatement(nameIdentifier),
211
206
  lua.createAssignmentStatement(nameIdentifier, createCallableTable(functionExpression)),
@@ -218,16 +213,13 @@ function transformFunctionLikeDeclaration(node, context) {
218
213
  }
219
214
  }
220
215
  }
221
- return isNamedFunctionExpression && isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node))
216
+ return isNamedFunctionExpression && isFunctionTypeWithProperties(context, context.checker.getTypeAtLocation(node))
222
217
  ? createCallableTable(functionExpression)
223
218
  : functionExpression;
224
219
  }
225
220
  exports.transformFunctionLikeDeclaration = transformFunctionLikeDeclaration;
226
221
  const transformFunctionDeclaration = (node, context) => {
227
222
  var _a;
228
- if ((0, annotations_1.getNodeAnnotations)(node).has(annotations_1.AnnotationKind.TupleReturn)) {
229
- context.diagnostics.push((0, diagnostics_1.annotationRemoved)(node, annotations_1.AnnotationKind.TupleReturn));
230
- }
231
223
  // Don't transform functions without body (overload declarations)
232
224
  if (node.body === undefined) {
233
225
  return undefined;
@@ -248,7 +240,7 @@ const transformFunctionDeclaration = (node, context) => {
248
240
  scope.functionDefinitions.set(name.symbolId, functionInfo);
249
241
  }
250
242
  // Wrap functions with properties into a callable table
251
- const wrappedFunction = node.name && isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node.name))
243
+ const wrappedFunction = node.name && isFunctionTypeWithProperties(context, context.checker.getTypeAtLocation(node.name))
252
244
  ? createCallableTable(functionExpression)
253
245
  : functionExpression;
254
246
  return (0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, name, wrappedFunction, node);
@@ -2,4 +2,5 @@ import * as ts from "typescript";
2
2
  import * as lua from "../../LuaAST";
3
3
  import { FunctionVisitor, TransformationContext } from "../context";
4
4
  export declare function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier;
5
+ export declare function transformIdentifierWithSymbol(context: TransformationContext, node: ts.Identifier, symbol: ts.Symbol | undefined): lua.Expression;
5
6
  export declare const transformIdentifierExpression: FunctionVisitor<ts.Identifier>;
@@ -1,82 +1,78 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformIdentifierExpression = exports.transformIdentifier = void 0;
3
+ exports.transformIdentifierExpression = exports.transformIdentifierWithSymbol = exports.transformIdentifier = void 0;
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../LuaAST");
6
6
  const builtins_1 = require("../builtins");
7
7
  const promise_1 = require("../builtins/promise");
8
8
  const context_1 = require("../context");
9
- const annotations_1 = require("../utils/annotations");
10
9
  const diagnostics_1 = require("../utils/diagnostics");
11
10
  const export_1 = require("../utils/export");
12
- const lualib_1 = require("../utils/lualib");
13
11
  const safe_names_1 = require("../utils/safe-names");
14
12
  const symbols_1 = require("../utils/symbols");
15
- const multi_1 = require("./language-extensions/multi");
16
- const operators_1 = require("./language-extensions/operators");
17
- const range_1 = require("./language-extensions/range");
18
- const table_1 = require("./language-extensions/table");
19
- const vararg_1 = require("./language-extensions/vararg");
20
13
  const optional_chaining_1 = require("./optional-chaining");
21
14
  const typescript_1 = require("../utils/typescript");
15
+ const language_extensions_1 = require("../utils/language-extensions");
16
+ const call_extension_1 = require("./language-extensions/call-extension");
17
+ const identifier_1 = require("./language-extensions/identifier");
22
18
  function transformIdentifier(context, identifier) {
19
+ return transformNonValueIdentifier(context, identifier, context.checker.getSymbolAtLocation(identifier));
20
+ }
21
+ exports.transformIdentifier = transformIdentifier;
22
+ function transformNonValueIdentifier(context, identifier, symbol) {
23
23
  if ((0, optional_chaining_1.isOptionalContinuation)(identifier)) {
24
24
  return lua.createIdentifier(identifier.text, undefined, context_1.tempSymbolId);
25
25
  }
26
- if ((0, multi_1.isMultiFunctionNode)(context, identifier)) {
27
- context.diagnostics.push((0, diagnostics_1.invalidMultiFunctionUse)(identifier));
28
- return lua.createAnonymousIdentifier(identifier);
29
- }
30
- if ((0, operators_1.isOperatorMapping)(context, identifier)) {
31
- context.diagnostics.push((0, diagnostics_1.invalidOperatorMappingUse)(identifier));
32
- }
33
- if ((0, table_1.isTableExtensionIdentifier)(context, identifier)) {
34
- context.diagnostics.push((0, diagnostics_1.invalidTableExtensionUse)(identifier));
35
- }
36
- if ((0, range_1.isRangeFunctionNode)(context, identifier)) {
37
- context.diagnostics.push((0, diagnostics_1.invalidRangeUse)(identifier));
38
- return lua.createAnonymousIdentifier(identifier);
39
- }
40
- if ((0, vararg_1.isVarargConstantNode)(context, identifier)) {
41
- context.diagnostics.push((0, diagnostics_1.invalidVarargUse)(identifier));
42
- return lua.createAnonymousIdentifier(identifier);
43
- }
44
- if ((0, annotations_1.isForRangeType)(context, identifier)) {
45
- context.diagnostics.push((0, diagnostics_1.annotationRemoved)(identifier, annotations_1.AnnotationKind.ForRange));
46
- }
47
- if ((0, promise_1.isPromiseClass)(context, identifier)) {
48
- (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Promise);
49
- return (0, promise_1.createPromiseIdentifier)(identifier);
26
+ const extensionKind = symbol
27
+ ? (0, language_extensions_1.getExtensionKindForSymbol)(context, symbol)
28
+ : (0, language_extensions_1.getExtensionKindForNode)(context, identifier);
29
+ if (extensionKind) {
30
+ if (call_extension_1.callExtensions.has(extensionKind)) {
31
+ context.diagnostics.push((0, diagnostics_1.invalidCallExtensionUse)(identifier));
32
+ // fall through
33
+ }
34
+ else if ((0, identifier_1.isIdentifierExtensionValue)(symbol, extensionKind)) {
35
+ (0, identifier_1.reportInvalidExtensionValue)(context, identifier, extensionKind);
36
+ return lua.createAnonymousIdentifier(identifier);
37
+ }
50
38
  }
51
39
  const type = context.checker.getTypeAtLocation(identifier);
52
40
  if ((0, typescript_1.isStandardLibraryType)(context, type, undefined)) {
53
41
  (0, builtins_1.checkForLuaLibType)(context, type);
42
+ if ((0, promise_1.isPromiseClass)(context, identifier)) {
43
+ return (0, promise_1.createPromiseIdentifier)(identifier);
44
+ }
54
45
  }
55
- const text = (0, safe_names_1.hasUnsafeIdentifierName)(context, identifier) ? (0, safe_names_1.createSafeName)(identifier.text) : identifier.text;
56
- const symbolId = (0, symbols_1.getIdentifierSymbolId)(context, identifier);
46
+ const text = (0, safe_names_1.hasUnsafeIdentifierName)(context, identifier, symbol)
47
+ ? (0, safe_names_1.createSafeName)(identifier.text)
48
+ : identifier.text;
49
+ const symbolId = (0, symbols_1.getIdentifierSymbolId)(context, identifier, symbol);
57
50
  return lua.createIdentifier(text, identifier, symbolId, identifier.text);
58
51
  }
59
- exports.transformIdentifier = transformIdentifier;
60
- const transformIdentifierExpression = (node, context) => {
61
- const symbol = context.checker.getSymbolAtLocation(node);
52
+ function transformIdentifierWithSymbol(context, node, symbol) {
62
53
  if (symbol) {
63
54
  const exportScope = (0, export_1.getSymbolExportScope)(context, symbol);
64
55
  if (exportScope) {
65
56
  const name = symbol.name;
66
- const text = (0, safe_names_1.hasUnsafeIdentifierName)(context, node) ? (0, safe_names_1.createSafeName)(name) : name;
67
- const symbolId = (0, symbols_1.getIdentifierSymbolId)(context, node);
57
+ const text = (0, safe_names_1.hasUnsafeIdentifierName)(context, node, symbol) ? (0, safe_names_1.createSafeName)(name) : name;
58
+ const symbolId = (0, symbols_1.getIdentifierSymbolId)(context, node, symbol);
68
59
  const identifier = lua.createIdentifier(text, node, symbolId, name);
69
60
  return (0, export_1.createExportedIdentifier)(context, identifier, exportScope);
70
61
  }
71
62
  }
72
- if (node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) {
73
- return lua.createNilLiteral();
74
- }
75
- const builtinResult = (0, builtins_1.transformBuiltinIdentifierExpression)(context, node);
63
+ const builtinResult = (0, builtins_1.transformBuiltinIdentifierExpression)(context, node, symbol);
76
64
  if (builtinResult) {
77
65
  return builtinResult;
78
66
  }
79
- return transformIdentifier(context, node);
67
+ return transformNonValueIdentifier(context, node, symbol);
68
+ }
69
+ exports.transformIdentifierWithSymbol = transformIdentifierWithSymbol;
70
+ const transformIdentifierExpression = (node, context) => {
71
+ if (node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) {
72
+ return lua.createNilLiteral(node);
73
+ }
74
+ const symbol = context.checker.getSymbolAtLocation(node);
75
+ return transformIdentifierWithSymbol(context, node, symbol);
80
76
  };
81
77
  exports.transformIdentifierExpression = transformIdentifierExpression;
82
78
  //# sourceMappingURL=identifier.js.map
@@ -0,0 +1,10 @@
1
+ import { TransformationContext } from "../../context";
2
+ import * as ts from "typescript";
3
+ import { ExtensionKind } from "../../utils/language-extensions";
4
+ import * as lua from "../../../LuaAST";
5
+ export declare const callExtensions: Set<ExtensionKind>;
6
+ export declare type LanguageExtensionCallTransformer = (context: TransformationContext, node: ts.CallExpression, extensionKind: ExtensionKind) => lua.Expression;
7
+ export declare type LanguageExtensionCallTransformerMap = {
8
+ [P in ExtensionKind]?: LanguageExtensionCallTransformer;
9
+ };
10
+ export declare function transformLanguageExtensionCallExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression | undefined;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformLanguageExtensionCallExpression = exports.callExtensions = void 0;
4
+ const language_extensions_1 = require("../../utils/language-extensions");
5
+ const operators_1 = require("./operators");
6
+ const table_1 = require("./table");
7
+ const allCallExtensionHandlers = {
8
+ ...operators_1.operatorExtensionTransformers,
9
+ ...table_1.tableExtensionTransformers,
10
+ };
11
+ exports.callExtensions = new Set(Object.keys(allCallExtensionHandlers));
12
+ table_1.tableNewExtensions.forEach(kind => exports.callExtensions.add(kind));
13
+ function transformLanguageExtensionCallExpression(context, node) {
14
+ const extensionKind = (0, language_extensions_1.getExtensionKindForNode)(context, node.expression);
15
+ if (!extensionKind)
16
+ return;
17
+ const transformer = allCallExtensionHandlers[extensionKind];
18
+ if (transformer) {
19
+ return transformer(context, node, extensionKind);
20
+ }
21
+ }
22
+ exports.transformLanguageExtensionCallExpression = transformLanguageExtensionCallExpression;
23
+ //# sourceMappingURL=call-extension.js.map
@@ -0,0 +1,5 @@
1
+ import * as ts from "typescript";
2
+ import { ExtensionKind } from "../../utils/language-extensions";
3
+ import { TransformationContext } from "../../context";
4
+ export declare function isIdentifierExtensionValue(symbol: ts.Symbol | undefined, extensionKind: ExtensionKind): boolean;
5
+ export declare function reportInvalidExtensionValue(context: TransformationContext, identifier: ts.Identifier, extensionKind: ExtensionKind): void;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reportInvalidExtensionValue = exports.isIdentifierExtensionValue = void 0;
4
+ const language_extensions_1 = require("../../utils/language-extensions");
5
+ const diagnostics_1 = require("../../utils/diagnostics");
6
+ const extensionKindToValueName = {
7
+ [language_extensions_1.ExtensionKind.MultiFunction]: "$multi",
8
+ [language_extensions_1.ExtensionKind.RangeFunction]: "$range",
9
+ [language_extensions_1.ExtensionKind.VarargConstant]: "$vararg",
10
+ };
11
+ function isIdentifierExtensionValue(symbol, extensionKind) {
12
+ return symbol !== undefined && extensionKindToValueName[extensionKind] === symbol.name;
13
+ }
14
+ exports.isIdentifierExtensionValue = isIdentifierExtensionValue;
15
+ function reportInvalidExtensionValue(context, identifier, extensionKind) {
16
+ if (extensionKind === language_extensions_1.ExtensionKind.MultiFunction) {
17
+ context.diagnostics.push((0, diagnostics_1.invalidMultiFunctionUse)(identifier));
18
+ }
19
+ else if (extensionKind === language_extensions_1.ExtensionKind.RangeFunction) {
20
+ context.diagnostics.push((0, diagnostics_1.invalidRangeUse)(identifier));
21
+ }
22
+ else if (extensionKind === language_extensions_1.ExtensionKind.VarargConstant) {
23
+ context.diagnostics.push((0, diagnostics_1.invalidVarargUse)(identifier));
24
+ }
25
+ }
26
+ exports.reportInvalidExtensionValue = reportInvalidExtensionValue;
27
+ //# sourceMappingURL=identifier.js.map
@@ -1,7 +1,6 @@
1
1
  import * as ts from "typescript";
2
2
  import * as lua from "../../../LuaAST";
3
3
  import { TransformationContext } from "../../context";
4
- export declare function isIterableType(type: ts.Type): boolean;
5
- export declare function returnsIterableType(context: TransformationContext, node: ts.CallExpression): boolean;
6
- export declare function isIterableExpression(context: TransformationContext, expression: ts.Expression): boolean;
7
4
  export declare function transformForOfIterableStatement(context: TransformationContext, statement: ts.ForOfStatement, block: lua.Block): lua.Statement;
5
+ export declare function transformForOfPairsIterableStatement(context: TransformationContext, statement: ts.ForOfStatement, block: lua.Block): lua.Statement;
6
+ export declare function transformForOfPairsKeyIterableStatement(context: TransformationContext, statement: ts.ForOfStatement, block: lua.Block): lua.Statement;
@@ -1,31 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformForOfIterableStatement = exports.isIterableExpression = exports.returnsIterableType = exports.isIterableType = void 0;
3
+ exports.transformForOfPairsKeyIterableStatement = exports.transformForOfPairsIterableStatement = exports.transformForOfIterableStatement = void 0;
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../../LuaAST");
6
- const extensions = require("../../utils/language-extensions");
7
6
  const utils_1 = require("../loops/utils");
8
7
  const variable_declaration_1 = require("../variable-declaration");
9
8
  const diagnostics_1 = require("../../utils/diagnostics");
10
9
  const utils_2 = require("../../../utils");
11
10
  const multi_1 = require("./multi");
12
- function isIterableType(type) {
13
- return extensions.isExtensionType(type, extensions.ExtensionKind.IterableType);
14
- }
15
- exports.isIterableType = isIterableType;
16
- function returnsIterableType(context, node) {
17
- const signature = context.checker.getResolvedSignature(node);
18
- const type = signature === null || signature === void 0 ? void 0 : signature.getReturnType();
19
- return type ? isIterableType(type) : false;
20
- }
21
- exports.returnsIterableType = returnsIterableType;
22
- function isIterableExpression(context, expression) {
23
- const type = context.checker.getTypeAtLocation(expression);
24
- return isIterableType(type);
25
- }
26
- exports.isIterableExpression = isIterableExpression;
27
- function transformForOfMultiIterableStatement(context, statement, block) {
28
- const luaIterator = context.transformExpression(statement.expression);
11
+ function transformForOfMultiIterableStatement(context, statement, block, luaIterator, invalidMultiUseDiagnostic) {
12
+ context.pushPrecedingStatements();
29
13
  let identifiers = [];
30
14
  if (ts.isVariableDeclarationList(statement.initializer)) {
31
15
  // Variables declared in for loop
@@ -35,7 +19,7 @@ function transformForOfMultiIterableStatement(context, statement, block) {
35
19
  identifiers = binding.elements.map(e => (0, variable_declaration_1.transformArrayBindingElement)(context, e));
36
20
  }
37
21
  else {
38
- context.diagnostics.push((0, diagnostics_1.invalidMultiIterableWithoutDestructuring)(binding));
22
+ context.diagnostics.push(invalidMultiUseDiagnostic(binding));
39
23
  }
40
24
  }
41
25
  else if (ts.isArrayLiteralExpression(statement.initializer)) {
@@ -48,22 +32,39 @@ function transformForOfMultiIterableStatement(context, statement, block) {
48
32
  }
49
33
  }
50
34
  else {
51
- context.diagnostics.push((0, diagnostics_1.invalidMultiIterableWithoutDestructuring)(statement.initializer));
35
+ context.diagnostics.push(invalidMultiUseDiagnostic(statement.initializer));
52
36
  }
53
37
  if (identifiers.length === 0) {
54
38
  identifiers.push(lua.createAnonymousIdentifier());
55
39
  }
40
+ block.statements.unshift(...context.popPrecedingStatements());
56
41
  return lua.createForInStatement(block, identifiers, [luaIterator], statement);
57
42
  }
58
43
  function transformForOfIterableStatement(context, statement, block) {
59
44
  var _a;
60
45
  const type = context.checker.getTypeAtLocation(statement.expression);
61
46
  if (((_a = type.aliasTypeArguments) === null || _a === void 0 ? void 0 : _a.length) === 2 && (0, multi_1.isMultiReturnType)(type.aliasTypeArguments[0])) {
62
- return transformForOfMultiIterableStatement(context, statement, block);
47
+ const luaIterator = context.transformExpression(statement.expression);
48
+ return transformForOfMultiIterableStatement(context, statement, block, luaIterator, diagnostics_1.invalidMultiIterableWithoutDestructuring);
63
49
  }
64
50
  const luaIterator = context.transformExpression(statement.expression);
65
51
  const identifier = (0, utils_1.transformForInitializer)(context, statement.initializer, block);
66
52
  return lua.createForInStatement(block, [identifier], [luaIterator], statement);
67
53
  }
68
54
  exports.transformForOfIterableStatement = transformForOfIterableStatement;
55
+ function transformForOfPairsIterableStatement(context, statement, block) {
56
+ const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [
57
+ context.transformExpression(statement.expression),
58
+ ]);
59
+ return transformForOfMultiIterableStatement(context, statement, block, pairsCall, diagnostics_1.invalidPairsIterableWithoutDestructuring);
60
+ }
61
+ exports.transformForOfPairsIterableStatement = transformForOfPairsIterableStatement;
62
+ function transformForOfPairsKeyIterableStatement(context, statement, block) {
63
+ const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [
64
+ context.transformExpression(statement.expression),
65
+ ]);
66
+ const identifier = (0, utils_1.transformForInitializer)(context, statement.initializer, block);
67
+ return lua.createForInStatement(block, [identifier], [pairsCall], statement);
68
+ }
69
+ exports.transformForOfPairsKeyIterableStatement = transformForOfPairsKeyIterableStatement;
69
70
  //# sourceMappingURL=iterable.js.map
@@ -8,4 +8,3 @@ export declare function isMultiReturnCall(context: TransformationContext, expres
8
8
  export declare function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean;
9
9
  export declare function isInMultiReturnFunction(context: TransformationContext, node: ts.Node): boolean;
10
10
  export declare function shouldMultiReturnCallBeWrapped(context: TransformationContext, node: ts.CallExpression): boolean;
11
- export declare function findMultiAssignmentViolations(context: TransformationContext, node: ts.ObjectLiteralExpression): ts.Node[];
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findMultiAssignmentViolations = exports.shouldMultiReturnCallBeWrapped = exports.isInMultiReturnFunction = exports.isMultiFunctionNode = exports.isMultiReturnCall = exports.returnsMultiType = exports.isMultiFunctionCall = exports.canBeMultiReturnType = exports.isMultiReturnType = void 0;
3
+ exports.shouldMultiReturnCallBeWrapped = exports.isInMultiReturnFunction = exports.isMultiFunctionNode = exports.isMultiReturnCall = exports.returnsMultiType = exports.isMultiFunctionCall = exports.canBeMultiReturnType = exports.isMultiReturnType = void 0;
4
4
  const ts = require("typescript");
5
5
  const extensions = require("../../utils/language-extensions");
6
+ const language_extensions_1 = require("../../utils/language-extensions");
6
7
  const typescript_1 = require("../../utils/typescript");
7
- const iterable_1 = require("./iterable");
8
- const diagnostics_1 = require("../../utils/diagnostics");
8
+ const multiReturnExtensionName = "__tstlMultiReturn";
9
9
  function isMultiReturnType(type) {
10
- return extensions.isExtensionType(type, extensions.ExtensionKind.MultiType);
10
+ return type.getProperty(multiReturnExtensionName) !== undefined;
11
11
  }
12
12
  exports.isMultiReturnType = isMultiReturnType;
13
13
  function canBeMultiReturnType(type) {
14
- return isMultiReturnType(type) || (type.isUnion() && type.types.some(canBeMultiReturnType));
14
+ return isMultiReturnType(type) || (type.isUnion() && type.types.some(t => canBeMultiReturnType(t)));
15
15
  }
16
16
  exports.canBeMultiReturnType = canBeMultiReturnType;
17
17
  function isMultiFunctionCall(context, expression) {
@@ -29,8 +29,9 @@ function isMultiReturnCall(context, expression) {
29
29
  }
30
30
  exports.isMultiReturnCall = isMultiReturnCall;
31
31
  function isMultiFunctionNode(context, node) {
32
- const symbol = context.checker.getSymbolAtLocation(node);
33
- return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.MultiFunction) : false;
32
+ return (ts.isIdentifier(node) &&
33
+ node.text === "$multi" &&
34
+ (0, language_extensions_1.getExtensionKindForNode)(context, node) === extensions.ExtensionKind.MultiFunction);
34
35
  }
35
36
  exports.isMultiFunctionNode = isMultiFunctionNode;
36
37
  function isInMultiReturnFunction(context, node) {
@@ -75,26 +76,11 @@ function shouldMultiReturnCallBeWrapped(context, node) {
75
76
  return false;
76
77
  }
77
78
  // LuaIterable in for...of
78
- if (ts.isForOfStatement(node.parent) && (0, iterable_1.isIterableExpression)(context, node)) {
79
+ if (ts.isForOfStatement(node.parent) &&
80
+ (0, language_extensions_1.getIterableExtensionKindForNode)(context, node) === language_extensions_1.IterableExtensionKind.Iterable) {
79
81
  return false;
80
82
  }
81
83
  return true;
82
84
  }
83
85
  exports.shouldMultiReturnCallBeWrapped = shouldMultiReturnCallBeWrapped;
84
- function findMultiAssignmentViolations(context, node) {
85
- const result = [];
86
- for (const element of node.properties) {
87
- if (!ts.isShorthandPropertyAssignment(element))
88
- continue;
89
- const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element);
90
- if (valueSymbol) {
91
- if (extensions.isExtensionValue(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) {
92
- context.diagnostics.push((0, diagnostics_1.invalidMultiFunctionUse)(element));
93
- result.push(element);
94
- }
95
- }
96
- }
97
- return result;
98
- }
99
- exports.findMultiAssignmentViolations = findMultiAssignmentViolations;
100
86
  //# sourceMappingURL=multi.js.map
@@ -1,5 +1,2 @@
1
- import * as ts from "typescript";
2
- import * as lua from "../../../LuaAST";
3
- import { TransformationContext } from "../../context";
4
- export declare function isOperatorMapping(context: TransformationContext, node: ts.CallExpression | ts.Identifier): boolean;
5
- export declare function transformOperatorMappingExpression(context: TransformationContext, node: ts.CallExpression, isOptionalCall: boolean): lua.Expression | undefined;
1
+ import { LanguageExtensionCallTransformerMap } from "./call-extension";
2
+ export declare const operatorExtensionTransformers: LanguageExtensionCallTransformerMap;