typescript-to-lua 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/CompilerOptions.d.ts +4 -3
  3. package/dist/LuaAST.d.ts +1 -0
  4. package/dist/LuaAST.js +14 -6
  5. package/dist/LuaLib.d.ts +4 -3
  6. package/dist/LuaLib.js +5 -4
  7. package/dist/LuaPrinter.d.ts +15 -4
  8. package/dist/LuaPrinter.js +79 -27
  9. package/dist/cli/diagnostics.js +2 -2
  10. package/dist/cli/parse.d.ts +1 -1
  11. package/dist/cli/parse.js +14 -0
  12. package/dist/cli/report.js +1 -1
  13. package/dist/cli/tsconfig.js +4 -4
  14. package/dist/lualib/ArrayFlat.lua +1 -1
  15. package/dist/lualib/ArrayFlatMap.lua +1 -1
  16. package/dist/lualib/ArrayIsArray.lua +1 -1
  17. package/dist/lualib/ArrayReduce.lua +7 -1
  18. package/dist/lualib/ArrayReduceRight.lua +7 -1
  19. package/dist/lualib/ArraySetLength.lua +1 -1
  20. package/dist/lualib/ArraySplice.lua +5 -5
  21. package/dist/lualib/Await.lua +39 -19
  22. package/dist/lualib/CloneDescriptor.lua +8 -8
  23. package/dist/lualib/Decorate.lua +1 -1
  24. package/dist/lualib/DelegatedYield.lua +1 -3
  25. package/dist/lualib/Delete.lua +6 -6
  26. package/dist/lualib/Error.lua +47 -44
  27. package/dist/lualib/Generator.lua +1 -5
  28. package/dist/lualib/InstanceOf.lua +1 -1
  29. package/dist/lualib/InstanceOfObject.lua +1 -1
  30. package/dist/lualib/Map.lua +130 -134
  31. package/dist/lualib/Number.lua +1 -1
  32. package/dist/lualib/NumberIsFinite.lua +1 -1
  33. package/dist/lualib/NumberToString.lua +3 -5
  34. package/dist/lualib/ObjectDefineProperty.lua +40 -8
  35. package/dist/lualib/ParseFloat.lua +9 -5
  36. package/dist/lualib/ParseInt.lua +15 -3
  37. package/dist/lualib/Promise.lua +36 -26
  38. package/dist/lualib/Set.lua +119 -123
  39. package/dist/lualib/SetDescriptor.lua +7 -1
  40. package/dist/lualib/SourceMapTraceBack.lua +19 -9
  41. package/dist/lualib/SparseArrayNew.lua +5 -0
  42. package/dist/lualib/SparseArrayPush.lua +9 -0
  43. package/dist/lualib/SparseArraySpread.lua +4 -0
  44. package/dist/lualib/StringAccess.lua +1 -1
  45. package/dist/lualib/StringCharCodeAt.lua +1 -1
  46. package/dist/lualib/StringEndsWith.lua +2 -2
  47. package/dist/lualib/StringPadEnd.lua +2 -2
  48. package/dist/lualib/StringPadStart.lua +2 -2
  49. package/dist/lualib/StringReplace.lua +12 -11
  50. package/dist/lualib/StringReplaceAll.lua +35 -0
  51. package/dist/lualib/StringSlice.lua +2 -2
  52. package/dist/lualib/StringSplit.lua +3 -3
  53. package/dist/lualib/StringStartsWith.lua +1 -1
  54. package/dist/lualib/StringSubstr.lua +1 -1
  55. package/dist/lualib/StringSubstring.lua +2 -2
  56. package/dist/lualib/Symbol.lua +3 -5
  57. package/dist/lualib/WeakMap.lua +40 -42
  58. package/dist/lualib/WeakSet.lua +36 -38
  59. package/dist/lualib/lualib_bundle.lua +705 -586
  60. package/dist/transformation/builtins/array.js +29 -30
  61. package/dist/transformation/builtins/console.js +2 -2
  62. package/dist/transformation/builtins/function.js +9 -10
  63. package/dist/transformation/builtins/global.js +8 -8
  64. package/dist/transformation/builtins/index.d.ts +1 -1
  65. package/dist/transformation/builtins/index.js +69 -36
  66. package/dist/transformation/builtins/math.js +4 -4
  67. package/dist/transformation/builtins/number.js +7 -7
  68. package/dist/transformation/builtins/object.d.ts +2 -1
  69. package/dist/transformation/builtins/object.js +12 -13
  70. package/dist/transformation/builtins/promise.js +9 -9
  71. package/dist/transformation/builtins/string.js +32 -31
  72. package/dist/transformation/builtins/symbol.js +3 -3
  73. package/dist/transformation/context/context.d.ts +12 -0
  74. package/dist/transformation/context/context.js +105 -6
  75. package/dist/transformation/index.js +1 -1
  76. package/dist/transformation/utils/annotations.d.ts +1 -3
  77. package/dist/transformation/utils/annotations.js +0 -2
  78. package/dist/transformation/utils/assignment-validation.js +8 -7
  79. package/dist/transformation/utils/diagnostics.d.ts +6 -0
  80. package/dist/transformation/utils/diagnostics.js +7 -5
  81. package/dist/transformation/utils/export.d.ts +3 -2
  82. package/dist/transformation/utils/export.js +14 -7
  83. package/dist/transformation/utils/function-context.js +8 -8
  84. package/dist/transformation/utils/lua-ast.d.ts +0 -1
  85. package/dist/transformation/utils/lua-ast.js +25 -35
  86. package/dist/transformation/utils/lualib.js +1 -1
  87. package/dist/transformation/utils/preceding-statements.d.ts +3 -0
  88. package/dist/transformation/utils/preceding-statements.js +11 -0
  89. package/dist/transformation/utils/safe-names.js +5 -5
  90. package/dist/transformation/utils/scope.d.ts +7 -0
  91. package/dist/transformation/utils/scope.js +77 -40
  92. package/dist/transformation/utils/symbols.js +6 -6
  93. package/dist/transformation/utils/typescript/index.d.ts +1 -0
  94. package/dist/transformation/utils/typescript/index.js +16 -1
  95. package/dist/transformation/utils/typescript/nodes.d.ts +2 -0
  96. package/dist/transformation/utils/typescript/nodes.js +21 -1
  97. package/dist/transformation/visitors/access.d.ts +3 -0
  98. package/dist/transformation/visitors/access.js +74 -47
  99. package/dist/transformation/visitors/async-await.js +5 -4
  100. package/dist/transformation/visitors/binary-expression/assignments.d.ts +3 -2
  101. package/dist/transformation/visitors/binary-expression/assignments.js +86 -77
  102. package/dist/transformation/visitors/binary-expression/bit.js +4 -4
  103. package/dist/transformation/visitors/binary-expression/compound.d.ts +5 -4
  104. package/dist/transformation/visitors/binary-expression/compound.js +69 -71
  105. package/dist/transformation/visitors/binary-expression/destructuring-assignments.d.ts +2 -2
  106. package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +65 -36
  107. package/dist/transformation/visitors/binary-expression/index.d.ts +3 -1
  108. package/dist/transformation/visitors/binary-expression/index.js +84 -40
  109. package/dist/transformation/visitors/block.js +6 -6
  110. package/dist/transformation/visitors/break-continue.js +4 -9
  111. package/dist/transformation/visitors/call.d.ts +3 -2
  112. package/dist/transformation/visitors/call.js +130 -143
  113. package/dist/transformation/visitors/class/decorators.js +3 -3
  114. package/dist/transformation/visitors/class/index.js +43 -39
  115. package/dist/transformation/visitors/class/members/accessors.js +6 -6
  116. package/dist/transformation/visitors/class/members/constructor.js +7 -7
  117. package/dist/transformation/visitors/class/members/fields.js +6 -6
  118. package/dist/transformation/visitors/class/members/method.js +6 -6
  119. package/dist/transformation/visitors/class/new.js +14 -16
  120. package/dist/transformation/visitors/class/setup.js +11 -11
  121. package/dist/transformation/visitors/class/utils.js +2 -2
  122. package/dist/transformation/visitors/conditional.js +34 -20
  123. package/dist/transformation/visitors/delete.js +8 -4
  124. package/dist/transformation/visitors/enum.js +8 -8
  125. package/dist/transformation/visitors/errors.js +30 -30
  126. package/dist/transformation/visitors/expression-list.d.ts +7 -0
  127. package/dist/transformation/visitors/expression-list.js +120 -0
  128. package/dist/transformation/visitors/expression-statement.js +10 -6
  129. package/dist/transformation/visitors/function.js +30 -32
  130. package/dist/transformation/visitors/identifier.js +26 -22
  131. package/dist/transformation/visitors/index.js +2 -2
  132. package/dist/transformation/visitors/language-extensions/iterable.js +7 -7
  133. package/dist/transformation/visitors/language-extensions/multi.d.ts +1 -1
  134. package/dist/transformation/visitors/language-extensions/multi.js +3 -3
  135. package/dist/transformation/visitors/language-extensions/operators.js +6 -6
  136. package/dist/transformation/visitors/language-extensions/range.js +6 -6
  137. package/dist/transformation/visitors/language-extensions/table.js +5 -5
  138. package/dist/transformation/visitors/literal.d.ts +1 -2
  139. package/dist/transformation/visitors/literal.js +87 -57
  140. package/dist/transformation/visitors/loops/do-while.js +35 -9
  141. package/dist/transformation/visitors/loops/for-in.js +4 -4
  142. package/dist/transformation/visitors/loops/for-of.js +13 -13
  143. package/dist/transformation/visitors/loops/for.js +28 -8
  144. package/dist/transformation/visitors/loops/utils.d.ts +1 -0
  145. package/dist/transformation/visitors/loops/utils.js +21 -10
  146. package/dist/transformation/visitors/modules/export.js +14 -15
  147. package/dist/transformation/visitors/modules/import.js +10 -10
  148. package/dist/transformation/visitors/namespace.js +13 -13
  149. package/dist/transformation/visitors/optional-chaining.d.ts +16 -0
  150. package/dist/transformation/visitors/optional-chaining.js +172 -0
  151. package/dist/transformation/visitors/return.d.ts +1 -0
  152. package/dist/transformation/visitors/return.js +40 -26
  153. package/dist/transformation/visitors/sourceFile.js +12 -9
  154. package/dist/transformation/visitors/spread.js +11 -11
  155. package/dist/transformation/visitors/switch.js +152 -30
  156. package/dist/transformation/visitors/template.js +10 -7
  157. package/dist/transformation/visitors/typeof.js +4 -2
  158. package/dist/transformation/visitors/typescript.js +1 -1
  159. package/dist/transformation/visitors/unary-expression.js +9 -9
  160. package/dist/transformation/visitors/variable-declaration.js +46 -32
  161. package/dist/transformation/visitors/void.d.ts +6 -0
  162. package/dist/transformation/visitors/void.js +20 -0
  163. package/dist/transpilation/bundle.d.ts +3 -0
  164. package/dist/transpilation/bundle.js +56 -13
  165. package/dist/transpilation/diagnostics.js +3 -3
  166. package/dist/transpilation/index.js +2 -2
  167. package/dist/transpilation/output-collector.js +2 -2
  168. package/dist/transpilation/plugins.js +1 -1
  169. package/dist/transpilation/resolve.js +26 -14
  170. package/dist/transpilation/transformers.js +45 -25
  171. package/dist/transpilation/transpile.js +6 -6
  172. package/dist/transpilation/transpiler.js +8 -8
  173. package/dist/transpilation/utils.js +5 -3
  174. package/dist/tstl.js +8 -8
  175. package/dist/utils.js +2 -2
  176. package/package.json +15 -12
  177. package/dist/lualib/OptionalChainAccess.lua +0 -6
  178. package/dist/lualib/OptionalFunctionCall.lua +0 -6
  179. package/dist/lualib/OptionalMethodCall.lua +0 -11
  180. package/dist/transformation/utils/transform.d.ts +0 -8
  181. package/dist/transformation/utils/transform.js +0 -14
  182. package/dist/transformation/visitors/jsx/jsx.d.ts +0 -9
  183. package/dist/transformation/visitors/jsx/jsx.js +0 -237
  184. package/dist/transformation/visitors/jsx/xhtml.d.ts +0 -3
  185. package/dist/transformation/visitors/jsx/xhtml.js +0 -260
@@ -2,46 +2,168 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transformSwitchStatement = void 0;
4
4
  const ts = require("typescript");
5
- const CompilerOptions_1 = require("../../CompilerOptions");
6
5
  const lua = require("../../LuaAST");
7
- const diagnostics_1 = require("../utils/diagnostics");
6
+ const preceding_statements_1 = require("../utils/preceding-statements");
8
7
  const scope_1 = require("../utils/scope");
9
- const transformSwitchStatement = (statement, context) => {
10
- if (context.luaTarget === CompilerOptions_1.LuaTarget.Universal || context.luaTarget === CompilerOptions_1.LuaTarget.Lua51) {
11
- context.diagnostics.push(diagnostics_1.unsupportedForTarget(statement, "Switch statements", CompilerOptions_1.LuaTarget.Lua51));
8
+ const binary_expression_1 = require("./binary-expression");
9
+ const containsBreakOrReturn = (nodes) => {
10
+ for (const s of nodes) {
11
+ if (ts.isBreakStatement(s) || ts.isReturnStatement(s)) {
12
+ return true;
13
+ }
14
+ else if (ts.isBlock(s) && containsBreakOrReturn(s.getChildren())) {
15
+ return true;
16
+ }
17
+ else if (s.kind === ts.SyntaxKind.SyntaxList && containsBreakOrReturn(s.getChildren())) {
18
+ return true;
19
+ }
20
+ }
21
+ return false;
22
+ };
23
+ const createOrExpression = (context, left, right, rightPrecedingStatements) => {
24
+ if (rightPrecedingStatements.length > 0) {
25
+ return (0, binary_expression_1.createShortCircuitBinaryExpressionPrecedingStatements)(context, left, right, rightPrecedingStatements, ts.SyntaxKind.BarBarToken);
26
+ }
27
+ else {
28
+ return [rightPrecedingStatements, lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator)];
12
29
  }
13
- const scope = scope_1.pushScope(context, scope_1.ScopeType.Switch);
14
- // Give the switch a unique name to prevent nested switches from acting up.
30
+ };
31
+ const coalesceCondition = (condition, conditionPrecedingStatements, switchVariable, expression, context) => {
32
+ const [precedingStatements, transformedExpression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression));
33
+ // Coalesce skipped statements
34
+ const comparison = lua.createBinaryExpression(switchVariable, transformedExpression, lua.SyntaxKind.EqualityOperator);
35
+ if (condition) {
36
+ return createOrExpression(context, condition, comparison, precedingStatements);
37
+ }
38
+ // Next condition
39
+ return [[...conditionPrecedingStatements, ...precedingStatements], comparison];
40
+ };
41
+ const transformSwitchStatement = (statement, context) => {
42
+ const scope = (0, scope_1.pushScope)(context, scope_1.ScopeType.Switch);
43
+ // Give the switch and condition accumulator a unique name to prevent nested switches from acting up.
15
44
  const switchName = `____switch${scope.id}`;
45
+ const conditionName = `____cond${scope.id}`;
16
46
  const switchVariable = lua.createIdentifier(switchName);
17
- let statements = [];
18
- // Starting from the back, concatenating ifs into one big if/elseif statement
19
- const concatenatedIf = statement.caseBlock.clauses.reduceRight((previousCondition, clause, index) => {
20
- if (ts.isDefaultClause(clause)) {
21
- // Skip default clause here (needs to be included to ensure index lines up with index later)
22
- return previousCondition;
47
+ const conditionVariable = lua.createIdentifier(conditionName);
48
+ // If the switch only has a default clause, wrap it in a single do.
49
+ // Otherwise, we need to generate a set of if statements to emulate the switch.
50
+ const statements = [];
51
+ const hoistedStatements = [];
52
+ const hoistedIdentifiers = [];
53
+ const clauses = statement.caseBlock.clauses;
54
+ if (clauses.length === 1 && ts.isDefaultClause(clauses[0])) {
55
+ const defaultClause = clauses[0].statements;
56
+ if (defaultClause.length) {
57
+ const { statements: defaultStatements, hoistedStatements: defaultHoistedStatements, hoistedIdentifiers: defaultHoistedIdentifiers, } = (0, scope_1.separateHoistedStatements)(context, context.transformStatements(defaultClause));
58
+ hoistedStatements.push(...defaultHoistedStatements);
59
+ hoistedIdentifiers.push(...defaultHoistedIdentifiers);
60
+ statements.push(lua.createDoStatement(defaultStatements));
61
+ }
62
+ }
63
+ else {
64
+ // Build up the condition for each if statement
65
+ let defaultTransformed = false;
66
+ let isInitialCondition = true;
67
+ let condition = undefined;
68
+ let conditionPrecedingStatements = [];
69
+ for (let i = 0; i < clauses.length; i++) {
70
+ const clause = clauses[i];
71
+ const previousClause = clauses[i - 1];
72
+ // Skip redundant default clauses, will be handled in final default case
73
+ if (i === 0 && ts.isDefaultClause(clause))
74
+ continue;
75
+ if (ts.isDefaultClause(clause) && previousClause && containsBreakOrReturn(previousClause.statements)) {
76
+ continue;
77
+ }
78
+ // Compute the condition for the if statement
79
+ if (!ts.isDefaultClause(clause)) {
80
+ [conditionPrecedingStatements, condition] = coalesceCondition(condition, conditionPrecedingStatements, switchVariable, clause.expression, context);
81
+ // Skip empty clauses unless final clause (i.e side-effects)
82
+ if (i !== clauses.length - 1 && clause.statements.length === 0)
83
+ continue;
84
+ // Declare or assign condition variable
85
+ if (isInitialCondition) {
86
+ statements.push(...conditionPrecedingStatements, lua.createVariableDeclarationStatement(conditionVariable, condition));
87
+ }
88
+ else {
89
+ [conditionPrecedingStatements, condition] = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
90
+ statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
91
+ }
92
+ isInitialCondition = false;
93
+ }
94
+ else {
95
+ // If the default is proceeded by empty clauses and will be emitted we may need to initialize the condition
96
+ if (isInitialCondition) {
97
+ statements.push(...conditionPrecedingStatements, lua.createVariableDeclarationStatement(conditionVariable, condition !== null && condition !== void 0 ? condition : lua.createBooleanLiteral(false)));
98
+ // Clear condition ot ensure it is not evaluated twice
99
+ condition = undefined;
100
+ conditionPrecedingStatements = [];
101
+ isInitialCondition = false;
102
+ }
103
+ // Allow default to fallthrough to final default clause
104
+ if (i === clauses.length - 1) {
105
+ // Evaluate the final condition that we may be skipping
106
+ if (condition) {
107
+ [conditionPrecedingStatements, condition] = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
108
+ statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
109
+ }
110
+ continue;
111
+ }
112
+ }
113
+ // Transform the clause and append the final break statement if necessary
114
+ const { statements: clauseStatements, hoistedStatements: clauseHoistedStatements, hoistedIdentifiers: clauseHoistedIdentifiers, } = (0, scope_1.separateHoistedStatements)(context, context.transformStatements(clause.statements));
115
+ if (i === clauses.length - 1 && !containsBreakOrReturn(clause.statements)) {
116
+ clauseStatements.push(lua.createBreakStatement());
117
+ }
118
+ hoistedStatements.push(...clauseHoistedStatements);
119
+ hoistedIdentifiers.push(...clauseHoistedIdentifiers);
120
+ // Remember that we transformed default clause so we don't duplicate hoisted statements later
121
+ if (ts.isDefaultClause(clause)) {
122
+ defaultTransformed = true;
123
+ }
124
+ // Push if statement for case
125
+ statements.push(lua.createIfStatement(conditionVariable, lua.createBlock(clauseStatements)));
126
+ // Clear condition for next clause
127
+ condition = undefined;
128
+ conditionPrecedingStatements = [];
129
+ }
130
+ // If no conditions above match, we need to create the final default case code-path,
131
+ // as we only handle fallthrough into defaults in the previous if statement chain
132
+ const start = clauses.findIndex(c => ts.isDefaultClause(c));
133
+ if (start >= 0) {
134
+ // Find the last clause that we can fallthrough to
135
+ const end = clauses.findIndex((clause, index) => index >= start && containsBreakOrReturn(clause.statements));
136
+ const { statements: defaultStatements, hoistedStatements: defaultHoistedStatements, hoistedIdentifiers: defaultHoistedIdentifiers, } = (0, scope_1.separateHoistedStatements)(context, context.transformStatements(clauses[start].statements));
137
+ // Only push hoisted statements if this is the first time we're transforming the default clause
138
+ if (!defaultTransformed) {
139
+ hoistedStatements.push(...defaultHoistedStatements);
140
+ hoistedIdentifiers.push(...defaultHoistedIdentifiers);
141
+ }
142
+ // Combine the fallthrough statements
143
+ for (const clause of clauses.slice(start + 1, end >= 0 ? end + 1 : undefined)) {
144
+ let statements = context.transformStatements(clause.statements);
145
+ // Drop hoisted statements as they were already added when clauses were initially transformed above
146
+ ({ statements } = (0, scope_1.separateHoistedStatements)(context, statements));
147
+ defaultStatements.push(...statements);
148
+ }
149
+ // Add the default clause if it has any statements
150
+ // The switch will always break on the final clause and skip execution if valid to do so
151
+ if (defaultStatements.length) {
152
+ statements.push(lua.createDoStatement(defaultStatements));
153
+ }
23
154
  }
24
- // If the clause condition holds, go to the correct label
25
- const condition = lua.createBinaryExpression(switchVariable, context.transformExpression(clause.expression), lua.SyntaxKind.EqualityOperator);
26
- const goto = lua.createGotoStatement(`${switchName}_case_${index}`);
27
- return lua.createIfStatement(condition, lua.createBlock([goto]), previousCondition);
28
- }, undefined);
29
- if (concatenatedIf) {
30
- statements.push(concatenatedIf);
31
155
  }
32
- const hasDefaultCase = statement.caseBlock.clauses.some(ts.isDefaultClause);
33
- statements.push(lua.createGotoStatement(`${switchName}_${hasDefaultCase ? "case_default" : "end"}`));
34
- for (const [index, clause] of statement.caseBlock.clauses.entries()) {
35
- const labelName = `${switchName}_case_${ts.isCaseClause(clause) ? index : "default"}`;
36
- statements.push(lua.createLabelStatement(labelName));
37
- statements.push(lua.createDoStatement(context.transformStatements(clause.statements)));
156
+ // Hoist the variable, function, and import statements to the top of the switch
157
+ statements.unshift(...hoistedStatements);
158
+ if (hoistedIdentifiers.length > 0) {
159
+ statements.unshift(lua.createVariableDeclarationStatement(hoistedIdentifiers));
38
160
  }
39
- statements.push(lua.createLabelStatement(`${switchName}_end`));
40
- statements = scope_1.performHoisting(context, statements);
41
- scope_1.popScope(context);
161
+ (0, scope_1.popScope)(context);
162
+ // Add the switch expression after hoisting
42
163
  const expression = context.transformExpression(statement.expression);
43
164
  statements.unshift(lua.createVariableDeclarationStatement(switchVariable, expression));
44
- return statements;
165
+ // Wrap the statements in a repeat until true statement to facilitate dynamic break/returns
166
+ return lua.createRepeatStatement(lua.createBlock(statements), lua.createBooleanLiteral(true));
45
167
  };
46
168
  exports.transformSwitchStatement = transformSwitchStatement;
47
169
  //# sourceMappingURL=switch.js.map
@@ -7,6 +7,7 @@ const function_context_1 = require("../utils/function-context");
7
7
  const lua_ast_1 = require("../utils/lua-ast");
8
8
  const types_1 = require("../utils/typescript/types");
9
9
  const call_1 = require("./call");
10
+ const expression_list_1 = require("./expression-list");
10
11
  // TODO: Source positions
11
12
  function getRawLiteral(node) {
12
13
  let text = node.getText();
@@ -21,14 +22,16 @@ const transformTemplateExpression = (node, context) => {
21
22
  if (head.length > 0) {
22
23
  parts.push(lua.createStringLiteral(head, node.head));
23
24
  }
24
- for (const span of node.templateSpans) {
25
- const expression = context.transformExpression(span.expression);
25
+ const transformedExpressions = (0, expression_list_1.transformOrderedExpressions)(context, node.templateSpans.map(s => s.expression));
26
+ for (let i = 0; i < node.templateSpans.length; ++i) {
27
+ const span = node.templateSpans[i];
28
+ const expression = transformedExpressions[i];
26
29
  const spanType = context.checker.getTypeAtLocation(span.expression);
27
- if (types_1.isStringType(context, spanType)) {
30
+ if ((0, types_1.isStringType)(context, spanType)) {
28
31
  parts.push(expression);
29
32
  }
30
33
  else {
31
- parts.push(lua_ast_1.wrapInToStringForConcat(expression));
34
+ parts.push((0, lua_ast_1.wrapInToStringForConcat)(expression));
32
35
  }
33
36
  const text = span.literal.text;
34
37
  if (text.length > 0) {
@@ -65,12 +68,12 @@ const transformTaggedTemplateExpression = (expression, context) => {
65
68
  // Evaluate if there is a self parameter to be used.
66
69
  const signature = context.checker.getResolvedSignature(expression);
67
70
  const signatureDeclaration = signature === null || signature === void 0 ? void 0 : signature.getDeclaration();
68
- const useSelfParameter = signatureDeclaration && function_context_1.getDeclarationContextType(context, signatureDeclaration) !== function_context_1.ContextType.Void;
71
+ const useSelfParameter = signatureDeclaration && (0, function_context_1.getDeclarationContextType)(context, signatureDeclaration) !== function_context_1.ContextType.Void;
69
72
  if (useSelfParameter) {
70
- return call_1.transformContextualCallExpression(context, expression, expressions, signature);
73
+ return (0, call_1.transformContextualCallExpression)(context, expression, expressions, signature);
71
74
  }
72
75
  // Argument evaluation.
73
- const callArguments = call_1.transformArguments(context, expressions, signature);
76
+ const callArguments = (0, call_1.transformArguments)(context, expressions, signature);
74
77
  const leftHandSideExpression = context.transformExpression(expression.tag);
75
78
  return lua.createCallExpression(leftHandSideExpression, callArguments);
76
79
  };
@@ -8,7 +8,7 @@ const lualib_1 = require("../utils/lualib");
8
8
  const binary_expression_1 = require("./binary-expression");
9
9
  const transformTypeOfExpression = (node, context) => {
10
10
  const innerExpression = context.transformExpression(node.expression);
11
- return lualib_1.transformLuaLibFunction(context, LuaLib_1.LuaLibFeature.TypeOf, node, innerExpression);
11
+ return (0, lualib_1.transformLuaLibFunction)(context, LuaLib_1.LuaLibFeature.TypeOf, node, innerExpression);
12
12
  };
13
13
  exports.transformTypeOfExpression = transformTypeOfExpression;
14
14
  function transformTypeOfBinaryExpression(context, node) {
@@ -43,7 +43,9 @@ function transformTypeOfBinaryExpression(context, node) {
43
43
  }
44
44
  const innerExpression = context.transformExpression(typeOfExpression.expression);
45
45
  const typeCall = lua.createCallExpression(lua.createIdentifier("type"), [innerExpression], typeOfExpression);
46
- return binary_expression_1.transformBinaryOperation(context, typeCall, comparedExpression, operator, node);
46
+ const [precedingStatements, result] = (0, binary_expression_1.transformBinaryOperation)(context, typeCall, comparedExpression, [], operator, node);
47
+ context.addPrecedingStatements(precedingStatements);
48
+ return result;
47
49
  }
48
50
  exports.transformTypeOfBinaryExpression = transformTypeOfBinaryExpression;
49
51
  //# sourceMappingURL=typeof.js.map
@@ -5,7 +5,7 @@ const ts = require("typescript");
5
5
  const assignment_validation_1 = require("../utils/assignment-validation");
6
6
  const transformAssertionExpression = (expression, context) => {
7
7
  if (!ts.isConstTypeReference(expression.type)) {
8
- assignment_validation_1.validateAssignment(context, expression, context.checker.getTypeAtLocation(expression.expression), context.checker.getTypeAtLocation(expression.type));
8
+ (0, assignment_validation_1.validateAssignment)(context, expression, context.checker.getTypeAtLocation(expression.expression), context.checker.getTypeAtLocation(expression.type));
9
9
  }
10
10
  return context.transformExpression(expression.expression);
11
11
  };
@@ -12,32 +12,32 @@ function transformUnaryExpressionStatement(context, node) {
12
12
  (expression.operator === ts.SyntaxKind.PlusPlusToken || expression.operator === ts.SyntaxKind.MinusMinusToken)) {
13
13
  // ++i, --i
14
14
  const replacementOperator = expression.operator === ts.SyntaxKind.PlusPlusToken ? ts.SyntaxKind.PlusToken : ts.SyntaxKind.MinusToken;
15
- return compound_1.transformCompoundAssignmentStatement(context, expression, expression.operand, ts.factory.createNumericLiteral(1), replacementOperator);
15
+ return (0, compound_1.transformCompoundAssignmentStatement)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), replacementOperator);
16
16
  }
17
17
  else if (ts.isPostfixUnaryExpression(expression)) {
18
18
  // i++, i--
19
19
  const replacementOperator = expression.operator === ts.SyntaxKind.PlusPlusToken ? ts.SyntaxKind.PlusToken : ts.SyntaxKind.MinusToken;
20
- return compound_1.transformCompoundAssignmentStatement(context, expression, expression.operand, ts.factory.createNumericLiteral(1), replacementOperator);
20
+ return (0, compound_1.transformCompoundAssignmentStatement)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), replacementOperator);
21
21
  }
22
22
  }
23
23
  exports.transformUnaryExpressionStatement = transformUnaryExpressionStatement;
24
24
  const transformPostfixUnaryExpression = (expression, context) => {
25
25
  switch (expression.operator) {
26
26
  case ts.SyntaxKind.PlusPlusToken:
27
- return compound_1.transformCompoundAssignmentExpression(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.PlusToken, true);
27
+ return (0, compound_1.transformCompoundAssignmentExpression)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.PlusToken, true);
28
28
  case ts.SyntaxKind.MinusMinusToken:
29
- return compound_1.transformCompoundAssignmentExpression(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.MinusToken, true);
29
+ return (0, compound_1.transformCompoundAssignmentExpression)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.MinusToken, true);
30
30
  default:
31
- utils_1.assertNever(expression.operator);
31
+ (0, utils_1.assertNever)(expression.operator);
32
32
  }
33
33
  };
34
34
  exports.transformPostfixUnaryExpression = transformPostfixUnaryExpression;
35
35
  const transformPrefixUnaryExpression = (expression, context) => {
36
36
  switch (expression.operator) {
37
37
  case ts.SyntaxKind.PlusPlusToken:
38
- return compound_1.transformCompoundAssignmentExpression(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.PlusToken, false);
38
+ return (0, compound_1.transformCompoundAssignmentExpression)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.PlusToken, false);
39
39
  case ts.SyntaxKind.MinusMinusToken:
40
- return compound_1.transformCompoundAssignmentExpression(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.MinusToken, false);
40
+ return (0, compound_1.transformCompoundAssignmentExpression)(context, expression, expression.operand, ts.factory.createNumericLiteral(1), ts.SyntaxKind.MinusToken, false);
41
41
  case ts.SyntaxKind.PlusToken:
42
42
  // TODO: Wrap with `Number`
43
43
  return context.transformExpression(expression.operand);
@@ -46,9 +46,9 @@ const transformPrefixUnaryExpression = (expression, context) => {
46
46
  case ts.SyntaxKind.ExclamationToken:
47
47
  return lua.createUnaryExpression(context.transformExpression(expression.operand), lua.SyntaxKind.NotOperator);
48
48
  case ts.SyntaxKind.TildeToken:
49
- return bit_1.transformUnaryBitOperation(context, expression, context.transformExpression(expression.operand), lua.SyntaxKind.BitwiseNotOperator);
49
+ return (0, bit_1.transformUnaryBitOperation)(context, expression, context.transformExpression(expression.operand), lua.SyntaxKind.BitwiseNotOperator);
50
50
  default:
51
- utils_1.assertNever(expression.operator);
51
+ (0, utils_1.assertNever)(expression.operator);
52
52
  }
53
53
  };
54
54
  exports.transformPrefixUnaryExpression = transformPrefixUnaryExpression;
@@ -9,6 +9,7 @@ const diagnostics_1 = require("../utils/diagnostics");
9
9
  const export_1 = require("../utils/export");
10
10
  const lua_ast_1 = require("../utils/lua-ast");
11
11
  const lualib_1 = require("../utils/lualib");
12
+ const preceding_statements_1 = require("../utils/preceding-statements");
12
13
  const identifier_1 = require("./identifier");
13
14
  const multi_1 = require("./language-extensions/multi");
14
15
  const literal_1 = require("./literal");
@@ -17,16 +18,21 @@ function transformArrayBindingElement(context, name) {
17
18
  return lua.createAnonymousIdentifier(name);
18
19
  }
19
20
  else if (ts.isIdentifier(name)) {
20
- return identifier_1.transformIdentifier(context, name);
21
+ return (0, identifier_1.transformIdentifier)(context, name);
21
22
  }
22
23
  else if (ts.isBindingElement(name)) {
23
- // TODO: It should always be true when called from `transformVariableDeclaration`,
24
- // but could be false from `transformForOfLuaIteratorStatement`.
25
- utils_1.assert(ts.isIdentifier(name.name));
26
- return identifier_1.transformIdentifier(context, name.name);
24
+ if (ts.isIdentifier(name.name)) {
25
+ return (0, identifier_1.transformIdentifier)(context, name.name);
26
+ }
27
+ else {
28
+ // ts.isBindingPattern(name.name)
29
+ const tempName = context.createTempNameForNode(name.name);
30
+ context.addPrecedingStatements(transformBindingPattern(context, name.name, tempName));
31
+ return tempName;
32
+ }
27
33
  }
28
34
  else {
29
- utils_1.assertNever(name);
35
+ (0, utils_1.assertNever)(name);
30
36
  }
31
37
  }
32
38
  exports.transformArrayBindingElement = transformArrayBindingElement;
@@ -48,11 +54,13 @@ function transformBindingPattern(context, pattern, table, propertyAccessStack =
48
54
  continue;
49
55
  }
50
56
  // Build the path to the table
51
- const tableExpression = propertyAccessStack.reduce((path, property) => lua.createTableIndexExpression(path, literal_1.transformPropertyName(context, property)), table);
57
+ const tableExpression = propertyAccessStack.reduce((path, property) => lua.createTableIndexExpression(path, (0, literal_1.transformPropertyName)(context, property)), table);
52
58
  // The identifier of the new variable
53
- const variableName = identifier_1.transformIdentifier(context, element.name);
59
+ const variableName = (0, identifier_1.transformIdentifier)(context, element.name);
54
60
  // The field to extract
55
- const propertyName = literal_1.transformPropertyName(context, (_a = element.propertyName) !== null && _a !== void 0 ? _a : element.name);
61
+ const elementName = (_a = element.propertyName) !== null && _a !== void 0 ? _a : element.name;
62
+ const [precedingStatements, propertyName] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, literal_1.transformPropertyName)(context, elementName));
63
+ result.push(...precedingStatements); // Keep property's preceding statements in order
56
64
  let expression;
57
65
  if (element.dotDotDotToken) {
58
66
  if (index !== pattern.elements.length - 1) {
@@ -78,20 +86,23 @@ function transformBindingPattern(context, pattern, table, propertyAccessStack =
78
86
  }
79
87
  }
80
88
  const excludedPropertiesTable = excludedProperties.map(e => lua.createTableFieldExpression(lua.createBooleanLiteral(true), lua.createStringLiteral(e.text, e)));
81
- expression = lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ObjectRest, undefined, tableExpression, lua.createTableExpression(excludedPropertiesTable));
89
+ expression = (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.ObjectRest, undefined, tableExpression, lua.createTableExpression(excludedPropertiesTable));
82
90
  }
83
91
  else {
84
- expression = lualib_1.transformLuaLibFunction(context, lualib_1.LuaLibFeature.ArraySlice, undefined, tableExpression, lua.createNumericLiteral(index));
92
+ expression = (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.ArraySlice, undefined, tableExpression, lua.createNumericLiteral(index));
85
93
  }
86
94
  }
87
95
  else {
88
96
  expression = lua.createTableIndexExpression(tableExpression, ts.isObjectBindingPattern(pattern) ? propertyName : lua.createNumericLiteral(index + 1));
89
97
  }
90
- result.push(...lua_ast_1.createLocalOrExportedOrGlobalDeclaration(context, variableName, expression));
98
+ result.push(...(0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, variableName, expression));
91
99
  if (element.initializer) {
92
- const identifier = export_1.addExportToIdentifier(context, variableName);
100
+ const identifier = (0, export_1.addExportToIdentifier)(context, variableName);
101
+ const tsInitializer = element.initializer;
102
+ const [initializerPrecedingStatements, initializer] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsInitializer));
93
103
  result.push(lua.createIfStatement(lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), lua.createBlock([
94
- lua.createAssignmentStatement(identifier, context.transformExpression(element.initializer)),
104
+ ...initializerPrecedingStatements,
105
+ lua.createAssignmentStatement(identifier, initializer),
95
106
  ])));
96
107
  }
97
108
  }
@@ -106,18 +117,21 @@ function transformBindingVariableDeclaration(context, bindingPattern, initialize
106
117
  if (ts.isObjectBindingPattern(bindingPattern) || bindingPattern.elements.some(isComplexBindingElement)) {
107
118
  let table;
108
119
  if (initializer !== undefined && ts.isIdentifier(initializer)) {
109
- table = identifier_1.transformIdentifier(context, initializer);
120
+ table = (0, identifier_1.transformIdentifier)(context, initializer);
110
121
  }
111
122
  else {
112
123
  // Contain the expression in a temporary variable
113
- table = lua.createAnonymousIdentifier();
114
124
  if (initializer) {
125
+ table = context.createTempNameForNode(initializer);
115
126
  let expression = context.transformExpression(initializer);
116
- if (multi_1.isMultiReturnCall(context, initializer)) {
117
- expression = lua_ast_1.wrapInTable(expression);
127
+ if ((0, multi_1.isMultiReturnCall)(context, initializer)) {
128
+ expression = (0, lua_ast_1.wrapInTable)(expression);
118
129
  }
119
130
  statements.push(lua.createVariableDeclarationStatement(table, expression));
120
131
  }
132
+ else {
133
+ table = lua.createAnonymousIdentifier();
134
+ }
121
135
  }
122
136
  statements.push(...transformBindingPattern(context, bindingPattern, table));
123
137
  return statements;
@@ -126,30 +140,30 @@ function transformBindingVariableDeclaration(context, bindingPattern, initialize
126
140
  ? bindingPattern.elements.map(e => transformArrayBindingElement(context, e))
127
141
  : lua.createAnonymousIdentifier();
128
142
  if (initializer) {
129
- if (multi_1.isMultiReturnCall(context, initializer)) {
143
+ if ((0, multi_1.isMultiReturnCall)(context, initializer)) {
130
144
  // Don't unpack LuaMultiReturn functions
131
- statements.push(...lua_ast_1.createLocalOrExportedOrGlobalDeclaration(context, vars, context.transformExpression(initializer), initializer));
145
+ statements.push(...(0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, vars, context.transformExpression(initializer), initializer));
132
146
  }
133
147
  else if (ts.isArrayLiteralExpression(initializer)) {
134
148
  // Don't unpack array literals
135
149
  const values = initializer.elements.length > 0
136
150
  ? initializer.elements.map(e => context.transformExpression(e))
137
151
  : lua.createNilLiteral();
138
- statements.push(...lua_ast_1.createLocalOrExportedOrGlobalDeclaration(context, vars, values, initializer));
152
+ statements.push(...(0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, vars, values, initializer));
139
153
  }
140
154
  else {
141
155
  // local vars = this.transpileDestructingAssignmentValue(node.initializer);
142
- const unpackedInitializer = lua_ast_1.createUnpackCall(context, context.transformExpression(initializer), initializer);
143
- statements.push(...lua_ast_1.createLocalOrExportedOrGlobalDeclaration(context, vars, unpackedInitializer, initializer));
156
+ const unpackedInitializer = (0, lua_ast_1.createUnpackCall)(context, context.transformExpression(initializer), initializer);
157
+ statements.push(...(0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, vars, unpackedInitializer, initializer));
144
158
  }
145
159
  }
146
160
  else {
147
- statements.push(...lua_ast_1.createLocalOrExportedOrGlobalDeclaration(context, vars, lua.createNilLiteral(), initializer));
161
+ statements.push(...(0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, vars, lua.createNilLiteral(), initializer));
148
162
  }
149
163
  for (const element of bindingPattern.elements) {
150
164
  if (!ts.isOmittedExpression(element) && element.initializer) {
151
- const variableName = identifier_1.transformIdentifier(context, element.name);
152
- const identifier = export_1.addExportToIdentifier(context, variableName);
165
+ const variableName = (0, identifier_1.transformIdentifier)(context, element.name);
166
+ const identifier = (0, export_1.addExportToIdentifier)(context, variableName);
153
167
  statements.push(lua.createIfStatement(lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), lua.createBlock([
154
168
  lua.createAssignmentStatement(identifier, context.transformExpression(element.initializer)),
155
169
  ])));
@@ -163,27 +177,27 @@ function transformVariableDeclaration(context, statement) {
163
177
  if (statement.initializer && statement.type) {
164
178
  const initializerType = context.checker.getTypeAtLocation(statement.initializer);
165
179
  const varType = context.checker.getTypeFromTypeNode(statement.type);
166
- assignment_validation_1.validateAssignment(context, statement.initializer, initializerType, varType);
180
+ (0, assignment_validation_1.validateAssignment)(context, statement.initializer, initializerType, varType);
167
181
  }
168
182
  if (ts.isIdentifier(statement.name)) {
169
183
  // Find variable identifier
170
- const identifierName = identifier_1.transformIdentifier(context, statement.name);
184
+ const identifierName = (0, identifier_1.transformIdentifier)(context, statement.name);
171
185
  const value = statement.initializer && context.transformExpression(statement.initializer);
172
- return lua_ast_1.createLocalOrExportedOrGlobalDeclaration(context, identifierName, value, statement);
186
+ return (0, lua_ast_1.createLocalOrExportedOrGlobalDeclaration)(context, identifierName, value, statement);
173
187
  }
174
188
  else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) {
175
189
  return transformBindingVariableDeclaration(context, statement.name, statement.initializer);
176
190
  }
177
191
  else {
178
- return utils_1.assertNever(statement.name);
192
+ return (0, utils_1.assertNever)(statement.name);
179
193
  }
180
194
  }
181
195
  exports.transformVariableDeclaration = transformVariableDeclaration;
182
196
  function checkVariableDeclarationList(context, node) {
183
197
  if ((node.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) === 0) {
184
198
  const token = node.getFirstToken();
185
- utils_1.assert(token);
186
- context.diagnostics.push(diagnostics_1.unsupportedVarDeclaration(token));
199
+ (0, utils_1.assert)(token);
200
+ context.diagnostics.push((0, diagnostics_1.unsupportedVarDeclaration)(token));
187
201
  }
188
202
  }
189
203
  exports.checkVariableDeclarationList = checkVariableDeclarationList;
@@ -0,0 +1,6 @@
1
+ import * as ts from "typescript";
2
+ import * as lua from "../../LuaAST";
3
+ import { TransformationContext } from "../context";
4
+ import { FunctionVisitor } from "../context/visitors";
5
+ export declare const transformVoidExpression: FunctionVisitor<ts.VoidExpression>;
6
+ export declare const transformVoidExpressionStatement: (node: ts.VoidExpression, context: TransformationContext) => lua.VariableDeclarationStatement;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.transformVoidExpressionStatement = exports.transformVoidExpression = void 0;
4
+ const ts = require("typescript");
5
+ const lua = require("../../LuaAST");
6
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
7
+ const transformVoidExpression = (node, context) => {
8
+ // If content is a literal it is safe to replace the entire expression with nil
9
+ if (!ts.isLiteralExpression(node.expression)) {
10
+ // local ____ = <expression>
11
+ context.addPrecedingStatements(lua.createVariableDeclarationStatement(lua.createAnonymousIdentifier(), context.transformExpression(node.expression)));
12
+ }
13
+ return lua.createNilLiteral(node);
14
+ };
15
+ exports.transformVoidExpression = transformVoidExpression;
16
+ const transformVoidExpressionStatement = (node, context) =>
17
+ // In case of a void expression statement we can omit the IIFE
18
+ lua.createVariableDeclarationStatement(lua.createAnonymousIdentifier(), context.transformExpression(node.expression), node);
19
+ exports.transformVoidExpressionStatement = transformVoidExpressionStatement;
20
+ //# sourceMappingURL=void.js.map
@@ -1,3 +1,6 @@
1
+ import { SourceNode } from "source-map";
1
2
  import * as ts from "typescript";
2
3
  import { EmitFile, ProcessedFile } from "./utils";
4
+ export declare const sourceMapTracebackBundlePlaceholder = "{#SourceMapTracebackBundle}";
5
+ export declare function printStackTraceBundleOverride(rootNode: SourceNode): string;
3
6
  export declare function getBundleResult(program: ts.Program, files: ProcessedFile[]): [ts.Diagnostic[], EmitFile];