typescript-to-lua 1.12.1 → 1.13.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 (26) hide show
  1. package/dist/transformation/utils/preceding-statements.d.ts +5 -1
  2. package/dist/transformation/utils/preceding-statements.js +1 -1
  3. package/dist/transformation/visitors/binary-expression/assignments.js +3 -3
  4. package/dist/transformation/visitors/binary-expression/compound.d.ts +0 -7
  5. package/dist/transformation/visitors/binary-expression/compound.js +40 -22
  6. package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +5 -5
  7. package/dist/transformation/visitors/binary-expression/index.d.ts +3 -2
  8. package/dist/transformation/visitors/binary-expression/index.js +12 -13
  9. package/dist/transformation/visitors/call.js +2 -2
  10. package/dist/transformation/visitors/class/index.js +1 -1
  11. package/dist/transformation/visitors/class/members/fields.js +1 -1
  12. package/dist/transformation/visitors/conditional.js +10 -10
  13. package/dist/transformation/visitors/expression-list.js +1 -1
  14. package/dist/transformation/visitors/function.js +2 -2
  15. package/dist/transformation/visitors/loops/do-while.js +2 -2
  16. package/dist/transformation/visitors/loops/for.js +2 -2
  17. package/dist/transformation/visitors/loops/utils.js +1 -1
  18. package/dist/transformation/visitors/optional-chaining.js +2 -2
  19. package/dist/transformation/visitors/sourceFile.js +1 -1
  20. package/dist/transformation/visitors/switch.js +15 -6
  21. package/dist/transformation/visitors/typeof.js +1 -1
  22. package/dist/transformation/visitors/variable-declaration.js +3 -3
  23. package/dist/transpilation/output-collector.d.ts +1 -1
  24. package/dist/transpilation/output-collector.js +3 -3
  25. package/dist/transpilation/resolve.js +19 -10
  26. package/package.json +1 -1
@@ -1,3 +1,7 @@
1
1
  import * as lua from "../../LuaAST";
2
2
  import { TransformationContext } from "../context";
3
- export declare function transformInPrecedingStatementScope<TReturn extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[]>(context: TransformationContext, transformer: () => TReturn): [lua.Statement[], TReturn];
3
+ export interface WithPrecedingStatements<T extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[]> {
4
+ precedingStatements: lua.Statement[];
5
+ result: T;
6
+ }
7
+ export declare function transformInPrecedingStatementScope<TReturn extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[]>(context: TransformationContext, transformer: () => TReturn): WithPrecedingStatements<TReturn>;
@@ -5,7 +5,7 @@ function transformInPrecedingStatementScope(context, transformer) {
5
5
  context.pushPrecedingStatements();
6
6
  const statementOrStatements = transformer();
7
7
  const precedingStatements = context.popPrecedingStatements();
8
- return [precedingStatements, statementOrStatements];
8
+ return { precedingStatements, result: statementOrStatements };
9
9
  }
10
10
  exports.transformInPrecedingStatementScope = transformInPrecedingStatementScope;
11
11
  //# sourceMappingURL=preceding-statements.js.map
@@ -72,7 +72,7 @@ function transformAssignmentWithRightPrecedingStatements(context, lhs, right, ri
72
72
  }
73
73
  exports.transformAssignmentWithRightPrecedingStatements = transformAssignmentWithRightPrecedingStatements;
74
74
  function transformDestructuredAssignmentExpression(context, expression) {
75
- let [rightPrecedingStatements, right] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
75
+ let { precedingStatements: rightPrecedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
76
76
  context.addPrecedingStatements(rightPrecedingStatements);
77
77
  if ((0, multi_1.isMultiReturnCall)(context, expression.right)) {
78
78
  right = (0, lua_ast_1.wrapInTable)(right);
@@ -96,7 +96,7 @@ function transformAssignmentExpression(context, expression) {
96
96
  return result;
97
97
  }
98
98
  if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) {
99
- const [precedingStatements, right] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
99
+ const { precedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
100
100
  const left = transformAssignmentLeftHandSideExpression(context, expression.left, precedingStatements.length > 0);
101
101
  context.addPrecedingStatements(precedingStatements);
102
102
  const rightExpr = (0, expression_list_1.moveToPrecedingTemp)(context, right, expression.right);
@@ -156,7 +156,7 @@ function transformAssignmentStatement(context, expression) {
156
156
  return statements;
157
157
  }
158
158
  else {
159
- const [precedingStatements, right] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
159
+ const { precedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.right));
160
160
  return transformAssignmentWithRightPrecedingStatements(context, expression.left, right, precedingStatements);
161
161
  }
162
162
  }
@@ -4,13 +4,6 @@ import { TransformationContext } from "../../context";
4
4
  type CompoundAssignmentToken = ts.SyntaxKind.BarToken | ts.SyntaxKind.PlusToken | ts.SyntaxKind.CaretToken | ts.SyntaxKind.MinusToken | ts.SyntaxKind.SlashToken | ts.SyntaxKind.PercentToken | ts.SyntaxKind.AsteriskToken | ts.SyntaxKind.AmpersandToken | ts.SyntaxKind.AsteriskAsteriskToken | ts.SyntaxKind.LessThanLessThanToken | ts.SyntaxKind.GreaterThanGreaterThanToken | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken | ts.SyntaxKind.BarBarToken | ts.SyntaxKind.AmpersandAmpersandToken | ts.SyntaxKind.QuestionQuestionToken;
5
5
  export declare const isCompoundAssignmentToken: (token: ts.BinaryOperator) => token is ts.CompoundAssignmentOperator;
6
6
  export declare const unwrapCompoundAssignmentToken: (token: ts.CompoundAssignmentOperator) => CompoundAssignmentToken;
7
- export declare function transformCompoundAssignment(context: TransformationContext, expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean): {
8
- statements: lua.Statement[];
9
- result: lua.Identifier;
10
- } | {
11
- statements: lua.Statement[];
12
- result: lua.TableIndexExpression;
13
- };
14
7
  export declare function transformCompoundAssignmentExpression(context: TransformationContext, expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean): lua.Expression;
15
8
  export declare function transformCompoundAssignmentStatement(context: TransformationContext, node: ts.Node, lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken): lua.Statement[];
16
9
  export {};
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformCompoundAssignmentStatement = exports.transformCompoundAssignmentExpression = exports.transformCompoundAssignment = exports.unwrapCompoundAssignmentToken = exports.isCompoundAssignmentToken = void 0;
3
+ exports.transformCompoundAssignmentStatement = exports.transformCompoundAssignmentExpression = exports.unwrapCompoundAssignmentToken = exports.isCompoundAssignmentToken = void 0;
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../../LuaAST");
6
6
  const utils_1 = require("../../../utils");
7
7
  const preceding_statements_1 = require("../../utils/preceding-statements");
8
8
  const index_1 = require("./index");
9
9
  const assignments_1 = require("./assignments");
10
+ const destructuring_assignments_1 = require("./destructuring-assignments");
11
+ const lualib_1 = require("../../utils/lualib");
10
12
  function isLuaExpressionWithSideEffect(expression) {
11
13
  return !(lua.isLiteral(expression) || lua.isIdentifier(expression));
12
14
  }
@@ -37,8 +39,12 @@ exports.isCompoundAssignmentToken = isCompoundAssignmentToken;
37
39
  const unwrapCompoundAssignmentToken = (token) => compoundToAssignmentTokens[token];
38
40
  exports.unwrapCompoundAssignmentToken = unwrapCompoundAssignmentToken;
39
41
  function transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix) {
42
+ if ((0, destructuring_assignments_1.isArrayLength)(context, lhs)) {
43
+ const { precedingStatements, result: lengthSetterStatement } = transformCompoundLengthSetter(context, expression, lhs, rhs, operator);
44
+ return { precedingStatements, result: lengthSetterStatement.expression };
45
+ }
40
46
  const left = (0, utils_1.cast)(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression);
41
- const [rightPrecedingStatements, right] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
47
+ const { precedingStatements: rightPrecedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
42
48
  if (lua.isTableIndexExpression(left)) {
43
49
  // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects
44
50
  // local __obj, __index = ${objExpression}, ${indexExpression};
@@ -52,17 +58,17 @@ function transformCompoundAssignment(context, expression, lhs, rhs, operator, is
52
58
  // ____obj[____index] = ____tmp ${replacementOperator} ${right};
53
59
  // return ____tmp
54
60
  const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression);
55
- const [precedingStatements, operatorExpression] = (0, index_1.transformBinaryOperation)(context, tmp, right, rightPrecedingStatements, operator, expression);
61
+ const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, tmp, right, rightPrecedingStatements, operator, expression);
56
62
  const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression);
57
63
  return {
58
- statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement],
64
+ precedingStatements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement],
59
65
  result: tmp,
60
66
  };
61
67
  }
62
68
  else {
63
69
  if (isSetterSkippingCompoundAssignmentOperator(operator)) {
64
70
  return {
65
- statements: [
71
+ precedingStatements: [
66
72
  objAndIndexDeclaration,
67
73
  ...transformSetterSkippingCompoundAssignment(accessExpression, operator, right, rightPrecedingStatements),
68
74
  ],
@@ -72,11 +78,11 @@ function transformCompoundAssignment(context, expression, lhs, rhs, operator, is
72
78
  // local ____tmp = ____obj[____index] ${replacementOperator} ${right};
73
79
  // ____obj[____index] = ____tmp;
74
80
  // return ____tmp
75
- const [precedingStatements, operatorExpression] = (0, index_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, expression);
81
+ const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, expression);
76
82
  const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression);
77
83
  const assignStatement = lua.createAssignmentStatement(accessExpression, tmp);
78
84
  return {
79
- statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement],
85
+ precedingStatements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement],
80
86
  result: tmp,
81
87
  };
82
88
  }
@@ -88,36 +94,42 @@ function transformCompoundAssignment(context, expression, lhs, rhs, operator, is
88
94
  // return ____tmp
89
95
  const tmpIdentifier = context.createTempNameForLuaExpression(left);
90
96
  const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left);
91
- const [precedingStatements, operatorExpression] = (0, index_1.transformBinaryOperation)(context, tmpIdentifier, right, rightPrecedingStatements, operator, expression);
97
+ const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, tmpIdentifier, right, rightPrecedingStatements, operator, expression);
92
98
  const assignStatements = (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, rightPrecedingStatements);
93
- return { statements: [tmpDeclaration, ...precedingStatements, ...assignStatements], result: tmpIdentifier };
99
+ return {
100
+ precedingStatements: [tmpDeclaration, ...precedingStatements, ...assignStatements],
101
+ result: tmpIdentifier,
102
+ };
94
103
  }
95
104
  else {
96
105
  if (rightPrecedingStatements.length > 0 && isSetterSkippingCompoundAssignmentOperator(operator)) {
97
106
  return {
98
- statements: transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements),
107
+ precedingStatements: transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements),
99
108
  result: left,
100
109
  };
101
110
  }
102
111
  // Simple expressions
103
112
  // ${left} = ${left} ${operator} ${right}
104
- const [precedingStatements, operatorExpression] = (0, index_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, expression);
113
+ const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, expression);
105
114
  const statements = (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, precedingStatements);
106
- return { statements, result: left };
115
+ return { precedingStatements: statements, result: left };
107
116
  }
108
117
  }
109
- exports.transformCompoundAssignment = transformCompoundAssignment;
110
118
  function transformCompoundAssignmentExpression(context, expression,
111
119
  // TODO: Change type to ts.LeftHandSideExpression?
112
120
  lhs, rhs, operator, isPostfix) {
113
- const { statements, result } = transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix);
114
- context.addPrecedingStatements(statements);
121
+ const { precedingStatements, result } = transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix);
122
+ context.addPrecedingStatements(precedingStatements);
115
123
  return result;
116
124
  }
117
125
  exports.transformCompoundAssignmentExpression = transformCompoundAssignmentExpression;
118
126
  function transformCompoundAssignmentStatement(context, node, lhs, rhs, operator) {
127
+ if ((0, destructuring_assignments_1.isArrayLength)(context, lhs)) {
128
+ const { precedingStatements, result: lengthSetterStatement } = transformCompoundLengthSetter(context, node, lhs, rhs, operator);
129
+ return [...precedingStatements, lengthSetterStatement];
130
+ }
119
131
  const left = (0, utils_1.cast)(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression);
120
- let [rightPrecedingStatements, right] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
132
+ const { precedingStatements: rightPrecedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
121
133
  if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) {
122
134
  // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects
123
135
  // local __obj, __index = ${objExpression}, ${indexExpression};
@@ -132,10 +144,9 @@ function transformCompoundAssignmentStatement(context, node, lhs, rhs, operator)
132
144
  ...transformSetterSkippingCompoundAssignment(accessExpression, operator, right, rightPrecedingStatements, node),
133
145
  ];
134
146
  }
135
- let operatorExpression;
136
- [rightPrecedingStatements, operatorExpression] = (0, index_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, node);
147
+ const { precedingStatements: rightPrecedingStatements2, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, accessExpression, right, rightPrecedingStatements, operator, node);
137
148
  const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression);
138
- return [objAndIndexDeclaration, ...rightPrecedingStatements, assignStatement];
149
+ return [objAndIndexDeclaration, ...rightPrecedingStatements2, assignStatement];
139
150
  }
140
151
  else {
141
152
  if (isSetterSkippingCompoundAssignmentOperator(operator)) {
@@ -143,9 +154,8 @@ function transformCompoundAssignmentStatement(context, node, lhs, rhs, operator)
143
154
  }
144
155
  // Simple statements
145
156
  // ${left} = ${left} ${replacementOperator} ${right}
146
- let operatorExpression;
147
- [rightPrecedingStatements, operatorExpression] = (0, index_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, node);
148
- return (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, rightPrecedingStatements);
157
+ const { precedingStatements: rightPrecedingStatements2, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, left, right, rightPrecedingStatements, operator, node);
158
+ return (0, assignments_1.transformAssignmentWithRightPrecedingStatements)(context, lhs, operatorExpression, rightPrecedingStatements2);
149
159
  }
150
160
  }
151
161
  exports.transformCompoundAssignmentStatement = transformCompoundAssignmentStatement;
@@ -174,4 +184,12 @@ function transformSetterSkippingCompoundAssignment(lhs, operator, right, rightPr
174
184
  lua.createIfStatement(condition, lua.createBlock([...rightPrecedingStatements, lua.createAssignmentStatement(lhs, right, node)]), undefined, node),
175
185
  ];
176
186
  }
187
+ function transformCompoundLengthSetter(context, node, lhs, rhs, operator) {
188
+ const { precedingStatements: rightPrecedingStatements, result: right } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rhs));
189
+ const table = context.transformExpression(lhs.expression);
190
+ const lengthExpression = lua.createUnaryExpression(table, lua.SyntaxKind.LengthOperator, lhs);
191
+ const { precedingStatements, result: operatorExpression } = (0, index_1.transformBinaryOperation)(context, lengthExpression, right, rightPrecedingStatements, operator, node);
192
+ const arrayLengthAssignment = lua.createExpressionStatement((0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.ArraySetLength, node, table, operatorExpression));
193
+ return { precedingStatements, result: arrayLengthAssignment };
194
+ }
177
195
  //# sourceMappingURL=compound.js.map
@@ -52,7 +52,7 @@ function transformArrayLiteralAssignmentPattern(context, node, root, rightHasPre
52
52
  const assignedVariable = context.createTempNameForLuaExpression(indexedRoot);
53
53
  const assignedVariableDeclaration = lua.createVariableDeclarationStatement(assignedVariable, indexedRoot);
54
54
  const nilCondition = lua.createBinaryExpression(assignedVariable, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator);
55
- const [defaultPrecedingStatements, defaultAssignmentStatements] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element.left, context.transformExpression(element.right)));
55
+ const { precedingStatements: defaultPrecedingStatements, result: defaultAssignmentStatements } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element.left, context.transformExpression(element.right)));
56
56
  // Keep preceding statements inside if block
57
57
  defaultAssignmentStatements.unshift(...defaultPrecedingStatements);
58
58
  const elseAssignmentStatements = (0, assignments_1.transformAssignment)(context, element.left, assignedVariable);
@@ -63,7 +63,7 @@ function transformArrayLiteralAssignmentPattern(context, node, root, rightHasPre
63
63
  case ts.SyntaxKind.Identifier:
64
64
  case ts.SyntaxKind.PropertyAccessExpression:
65
65
  case ts.SyntaxKind.ElementAccessExpression:
66
- const [precedingStatements, statements] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element, indexedRoot, rightHasPrecedingStatements));
66
+ const { precedingStatements, result: statements } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element, indexedRoot, rightHasPrecedingStatements));
67
67
  return [...precedingStatements, ...statements]; // Keep preceding statements in order
68
68
  case ts.SyntaxKind.SpreadElement:
69
69
  if (index !== node.elements.length - 1) {
@@ -71,7 +71,7 @@ function transformArrayLiteralAssignmentPattern(context, node, root, rightHasPre
71
71
  return [];
72
72
  }
73
73
  const restElements = (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.ArraySlice, undefined, root, lua.createNumericLiteral(index));
74
- const [spreadPrecedingStatements, spreadStatements] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element.expression, restElements, rightHasPrecedingStatements));
74
+ const { precedingStatements: spreadPrecedingStatements, result: spreadStatements } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, assignments_1.transformAssignment)(context, element.expression, restElements, rightHasPrecedingStatements));
75
75
  return [...spreadPrecedingStatements, ...spreadStatements]; // Keep preceding statements in order
76
76
  case ts.SyntaxKind.OmittedExpression:
77
77
  return [];
@@ -146,12 +146,12 @@ function transformPropertyAssignment(context, node, root, rightHasPrecedingState
146
146
  // Access expressions need their table and index expressions cached to preserve execution order
147
147
  const left = (0, utils_1.cast)(context.transformExpression(node.initializer.left), lua.isTableIndexExpression);
148
148
  const rightExpression = node.initializer.right;
149
- const [defaultPrecedingStatements, defaultExpression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rightExpression));
149
+ const { precedingStatements: defaultPrecedingStatements, result: defaultExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(rightExpression));
150
150
  const tableTemp = context.createTempNameForLuaExpression(left.table);
151
151
  const indexTemp = context.createTempNameForLuaExpression(left.index);
152
152
  const tempsDeclaration = lua.createVariableDeclarationStatement([tableTemp, indexTemp], [left.table, left.index]);
153
153
  // obj[index] = extractingExpression ?? defaultExpression
154
- const [rightPrecedingStatements, rhs] = (0, _1.transformBinaryOperation)(context, extractingExpression, defaultExpression, defaultPrecedingStatements, ts.SyntaxKind.QuestionQuestionToken, node.initializer);
154
+ const { precedingStatements: rightPrecedingStatements, result: rhs } = (0, _1.transformBinaryOperation)(context, extractingExpression, defaultExpression, defaultPrecedingStatements, ts.SyntaxKind.QuestionQuestionToken, node.initializer);
155
155
  const assignStatement = lua.createAssignmentStatement(lua.createTableIndexExpression(tableTemp, indexTemp), rhs);
156
156
  destructureAssignmentStatements = [tempsDeclaration, ...rightPrecedingStatements, assignStatement];
157
157
  }
@@ -2,10 +2,11 @@ import * as ts from "typescript";
2
2
  import * as lua from "../../../LuaAST";
3
3
  import { FunctionVisitor, TransformationContext } from "../../context";
4
4
  import { BitOperator } from "./bit";
5
+ import { WithPrecedingStatements } from "../../utils/preceding-statements";
5
6
  type ShortCircuitOperator = ts.SyntaxKind.AmpersandAmpersandToken | ts.SyntaxKind.BarBarToken | ts.SyntaxKind.QuestionQuestionToken;
6
7
  type SimpleOperator = ts.AdditiveOperatorOrHigher | Exclude<ts.RelationalOperator, ts.SyntaxKind.InstanceOfKeyword | ts.SyntaxKind.InKeyword> | ts.EqualityOperator | ts.LogicalOperator;
7
- export declare function createShortCircuitBinaryExpressionPrecedingStatements(context: TransformationContext, lhs: lua.Expression, rhs: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: ShortCircuitOperator, node?: ts.BinaryExpression): [lua.Statement[], lua.Expression];
8
- export declare function transformBinaryOperation(context: TransformationContext, left: lua.Expression, right: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node): [lua.Statement[], lua.Expression];
8
+ export declare function createShortCircuitBinaryExpressionPrecedingStatements(context: TransformationContext, lhs: lua.Expression, rhs: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: ShortCircuitOperator, node?: ts.BinaryExpression): WithPrecedingStatements<lua.Expression>;
9
+ export declare function transformBinaryOperation(context: TransformationContext, left: lua.Expression, right: lua.Expression, rightPrecedingStatements: lua.Statement[], operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node): WithPrecedingStatements<lua.Expression>;
9
10
  export declare const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression>;
10
11
  export declare function transformBinaryExpressionStatement(context: TransformationContext, node: ts.ExpressionStatement): lua.Statement[] | lua.Statement | undefined;
11
12
  export {};
@@ -78,23 +78,23 @@ function createShortCircuitBinaryExpressionPrecedingStatements(context, lhs, rhs
78
78
  break;
79
79
  }
80
80
  const ifStatement = lua.createIfStatement(condition, lua.createBlock([...rightPrecedingStatements, lua.createAssignmentStatement(conditionIdentifier, rhs)]), undefined, node === null || node === void 0 ? void 0 : node.left);
81
- return [[assignmentStatement, ifStatement], conditionIdentifier];
81
+ return { precedingStatements: [assignmentStatement, ifStatement], result: conditionIdentifier };
82
82
  }
83
83
  exports.createShortCircuitBinaryExpressionPrecedingStatements = createShortCircuitBinaryExpressionPrecedingStatements;
84
84
  function transformShortCircuitBinaryExpression(context, node, operator) {
85
85
  const lhs = context.transformExpression(node.left);
86
- const [rightPrecedingStatements, rhs] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(node.right));
87
- return transformBinaryOperation(context, lhs, rhs, rightPrecedingStatements, operator, node);
86
+ const { precedingStatements, result } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(node.right));
87
+ return transformBinaryOperation(context, lhs, result, precedingStatements, operator, node);
88
88
  }
89
89
  function transformBinaryOperation(context, left, right, rightPrecedingStatements, operator, node) {
90
90
  if (rightPrecedingStatements.length > 0 && isShortCircuitOperator(operator)) {
91
91
  (0, utils_1.assert)(ts.isBinaryExpression(node));
92
92
  return createShortCircuitBinaryExpressionPrecedingStatements(context, left, right, rightPrecedingStatements, operator, node);
93
93
  }
94
- return [
95
- rightPrecedingStatements,
96
- transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node),
97
- ];
94
+ return {
95
+ precedingStatements: rightPrecedingStatements,
96
+ result: transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node),
97
+ };
98
98
  }
99
99
  exports.transformBinaryOperation = transformBinaryOperation;
100
100
  const transformBinaryExpression = (node, context) => {
@@ -127,7 +127,7 @@ const transformBinaryExpression = (node, context) => {
127
127
  }
128
128
  case ts.SyntaxKind.CommaToken: {
129
129
  const statements = context.transformStatements(ts.factory.createExpressionStatement(node.left));
130
- const [precedingStatements, result] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(node.right));
130
+ const { precedingStatements, result } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(node.right));
131
131
  statements.push(...precedingStatements);
132
132
  context.addPrecedingStatements(statements);
133
133
  return result;
@@ -135,14 +135,13 @@ const transformBinaryExpression = (node, context) => {
135
135
  case ts.SyntaxKind.QuestionQuestionToken:
136
136
  case ts.SyntaxKind.AmpersandAmpersandToken:
137
137
  case ts.SyntaxKind.BarBarToken: {
138
- const [precedingStatements, result] = transformShortCircuitBinaryExpression(context, node, operator);
138
+ const { precedingStatements, result } = transformShortCircuitBinaryExpression(context, node, operator);
139
139
  context.addPrecedingStatements(precedingStatements);
140
140
  return result;
141
141
  }
142
142
  }
143
- let [precedingStatements, [lhs, rhs]] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, expression_list_1.transformOrderedExpressions)(context, [node.left, node.right]));
144
- let result;
145
- [precedingStatements, result] = transformBinaryOperation(context, lhs, rhs, precedingStatements, operator, node);
143
+ const { precedingStatements: orderedExpressionPrecedingStatements, result: [lhs, rhs], } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, expression_list_1.transformOrderedExpressions)(context, [node.left, node.right]));
144
+ const { precedingStatements, result } = transformBinaryOperation(context, lhs, rhs, orderedExpressionPrecedingStatements, operator, node);
146
145
  context.addPrecedingStatements(precedingStatements);
147
146
  return result;
148
147
  };
@@ -174,7 +173,7 @@ function transformNullishCoalescingOperationNoPrecedingStatements(context, node,
174
173
  // Check if we can take a shortcut to 'lhs or rhs' if the left-hand side cannot be 'false'.
175
174
  if ((0, typescript_1.canBeFalsyWhenNotNull)(context, lhsType)) {
176
175
  // reuse logic from case with preceding statements
177
- const [precedingStatements, result] = createShortCircuitBinaryExpressionPrecedingStatements(context, transformedLeft, transformedRight, [], ts.SyntaxKind.QuestionQuestionToken, node);
176
+ const { precedingStatements, result } = createShortCircuitBinaryExpressionPrecedingStatements(context, transformedLeft, transformedRight, [], ts.SyntaxKind.QuestionQuestionToken, node);
178
177
  context.addPrecedingStatements(precedingStatements);
179
178
  return result;
180
179
  }
@@ -55,7 +55,7 @@ function transformCallWithArguments(context, callExpression, transformedArgument
55
55
  return [call, transformedArguments];
56
56
  }
57
57
  function transformCallAndArguments(context, callExpression, params, signature, callContext) {
58
- const [argPrecedingStatements, transformedArguments] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformArguments(context, params, signature, callContext));
58
+ const { precedingStatements: argPrecedingStatements, result: transformedArguments } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformArguments(context, params, signature, callContext));
59
59
  return transformCallWithArguments(context, callExpression, transformedArguments, argPrecedingStatements);
60
60
  }
61
61
  exports.transformCallAndArguments = transformCallAndArguments;
@@ -82,7 +82,7 @@ function transformContextualCallExpression(context, node, args, signature) {
82
82
  return (0, optional_chaining_1.transformOptionalChain)(context, node);
83
83
  }
84
84
  const left = ts.isCallExpression(node) ? getCalledExpression(node) : node.tag;
85
- let [argPrecedingStatements, transformedArguments] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformArguments(context, args, signature));
85
+ let { precedingStatements: argPrecedingStatements, result: transformedArguments } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformArguments(context, args, signature));
86
86
  if (ts.isPropertyAccessExpression(left) &&
87
87
  ts.isIdentifier(left.name) &&
88
88
  (0, safe_names_1.isValidLuaIdentifier)(left.name.text, context.options) &&
@@ -20,7 +20,7 @@ const transformClassDeclaration = (declaration, context) => {
20
20
  // If declaration is a default export, transform to export variable assignment instead
21
21
  if ((0, export_1.hasDefaultExportModifier)(declaration)) {
22
22
  // Class declaration including assignment to ____exports.default are in preceding statements
23
- const [precedingStatements] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
23
+ const { precedingStatements } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
24
24
  transformClassAsExpression(declaration, context);
25
25
  return [];
26
26
  });
@@ -22,7 +22,7 @@ exports.createPropertyDecoratingExpression = createPropertyDecoratingExpression;
22
22
  function transformClassInstanceFields(context, instanceFields) {
23
23
  const statements = [];
24
24
  for (const f of instanceFields) {
25
- const [precedingStatements, statement] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
25
+ const { precedingStatements, result: statement } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
26
26
  // Get identifier
27
27
  const fieldName = (0, literal_1.transformPropertyName)(context, f.name);
28
28
  const value = f.initializer ? context.transformExpression(f.initializer) : undefined;
@@ -10,12 +10,12 @@ const typescript_1 = require("../utils/typescript");
10
10
  const diagnostics_1 = require("../utils/diagnostics");
11
11
  function transformProtectedConditionalExpression(context, expression, condition, whenTrue, whenFalse) {
12
12
  const tempVar = context.createTempNameForNode(expression.condition);
13
- const trueStatements = whenTrue[0].concat(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue[1], expression.whenTrue));
14
- const falseStatements = whenFalse[0].concat(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenFalse[1], expression.whenFalse));
13
+ const trueStatements = whenTrue.precedingStatements.concat(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue.result, expression.whenTrue));
14
+ const falseStatements = whenFalse.precedingStatements.concat(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenFalse.result, expression.whenFalse));
15
15
  context.addPrecedingStatements([
16
16
  lua.createVariableDeclarationStatement(tempVar, undefined, expression.condition),
17
- ...condition[0],
18
- lua.createIfStatement(condition[1], lua.createBlock(trueStatements, expression.whenTrue), lua.createBlock(falseStatements, expression.whenFalse), expression),
17
+ ...condition.precedingStatements,
18
+ lua.createIfStatement(condition.result, lua.createBlock(trueStatements, expression.whenTrue), lua.createBlock(falseStatements, expression.whenFalse), expression),
19
19
  ]);
20
20
  return lua.cloneIdentifier(tempVar);
21
21
  }
@@ -25,15 +25,15 @@ const transformConditionalExpression = (expression, context) => {
25
25
  const condition = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.condition));
26
26
  const whenTrue = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.whenTrue));
27
27
  const whenFalse = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression.whenFalse));
28
- if (whenTrue[0].length > 0 ||
29
- whenFalse[0].length > 0 ||
28
+ if (whenTrue.precedingStatements.length > 0 ||
29
+ whenFalse.precedingStatements.length > 0 ||
30
30
  (0, typescript_1.canBeFalsy)(context, context.checker.getTypeAtLocation(expression.whenTrue))) {
31
31
  return transformProtectedConditionalExpression(context, expression, condition, whenTrue, whenFalse);
32
32
  }
33
33
  // condition and v1 or v2
34
- context.addPrecedingStatements(condition[0]);
35
- const conditionAnd = lua.createBinaryExpression(condition[1], whenTrue[1], lua.SyntaxKind.AndOperator);
36
- return lua.createBinaryExpression(conditionAnd, whenFalse[1], lua.SyntaxKind.OrOperator, expression);
34
+ context.addPrecedingStatements(condition.precedingStatements);
35
+ const conditionAnd = lua.createBinaryExpression(condition.result, whenTrue.result, lua.SyntaxKind.AndOperator);
36
+ return lua.createBinaryExpression(conditionAnd, whenFalse.result, lua.SyntaxKind.OrOperator, expression);
37
37
  };
38
38
  exports.transformConditionalExpression = transformConditionalExpression;
39
39
  function transformIfStatement(statement, context) {
@@ -47,7 +47,7 @@ function transformIfStatement(statement, context) {
47
47
  if (statement.elseStatement) {
48
48
  if (ts.isIfStatement(statement.elseStatement)) {
49
49
  const tsElseStatement = statement.elseStatement;
50
- const [precedingStatements, elseStatement] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformIfStatement(tsElseStatement, context));
50
+ const { precedingStatements, result: elseStatement } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformIfStatement(tsElseStatement, context));
51
51
  // If else-if condition generates preceding statements, we can't use elseif, we have to break it down:
52
52
  // if conditionA then
53
53
  // ...
@@ -34,7 +34,7 @@ function transformExpressions(context, expressions) {
34
34
  const transformedExpressions = [];
35
35
  let lastPrecedingStatementsIndex = -1;
36
36
  for (let i = 0; i < expressions.length; ++i) {
37
- const [expressionPrecedingStatements, expression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expressions[i]));
37
+ const { precedingStatements: expressionPrecedingStatements, result: expression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expressions[i]));
38
38
  transformedExpressions.push(expression);
39
39
  if (expressionPrecedingStatements.length > 0) {
40
40
  lastPrecedingStatementsIndex = i;
@@ -69,7 +69,7 @@ function isFunctionTypeWithProperties(context, functionType) {
69
69
  exports.isFunctionTypeWithProperties = isFunctionTypeWithProperties;
70
70
  function transformFunctionBodyContent(context, body) {
71
71
  if (!ts.isBlock(body)) {
72
- const [precedingStatements, returnStatement] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, return_1.transformExpressionBodyToReturnStatement)(context, body));
72
+ const { precedingStatements, result: returnStatement } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, return_1.transformExpressionBodyToReturnStatement)(context, body));
73
73
  return [...precedingStatements, returnStatement];
74
74
  }
75
75
  const bodyStatements = (0, scope_1.performHoisting)(context, context.transformStatements(body.statements));
@@ -90,7 +90,7 @@ function transformFunctionBodyHeader(context, bodyScope, parameters, spreadIdent
90
90
  }
91
91
  // Binding pattern
92
92
  const name = declaration.name;
93
- const [precedingStatements, bindings] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, name, identifier));
93
+ const { precedingStatements, result: bindings } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, name, identifier));
94
94
  bindingPatternDeclarations.push(...precedingStatements, ...bindings);
95
95
  }
96
96
  else if (declaration.initializer !== undefined) {
@@ -9,7 +9,7 @@ const transformWhileStatement = (statement, context) => {
9
9
  // Check if we need to add diagnostic about Lua truthiness
10
10
  (0, conditional_1.checkOnlyTruthyCondition)(statement.expression, context);
11
11
  const body = (0, utils_1.transformLoopBody)(context, statement);
12
- let [conditionPrecedingStatements, condition] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
12
+ let { precedingStatements: conditionPrecedingStatements, result: condition } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
13
13
  // If condition has preceding statements, ensure they are executed every iteration by using the form:
14
14
  //
15
15
  // while true do
@@ -31,7 +31,7 @@ const transformDoStatement = (statement, context) => {
31
31
  // Check if we need to add diagnostic about Lua truthiness
32
32
  (0, conditional_1.checkOnlyTruthyCondition)(statement.expression, context);
33
33
  const body = lua.createDoStatement((0, utils_1.transformLoopBody)(context, statement));
34
- let [conditionPrecedingStatements, condition] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, utils_1.invertCondition)(context.transformExpression(statement.expression)));
34
+ let { precedingStatements: conditionPrecedingStatements, result: condition } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, utils_1.invertCondition)(context.transformExpression(statement.expression)));
35
35
  // If condition has preceding statements, ensure they are executed every iteration by using the form:
36
36
  //
37
37
  // repeat
@@ -21,9 +21,9 @@ const transformForStatement = (statement, context) => {
21
21
  const body = (0, utils_1.transformLoopBody)(context, statement);
22
22
  let condition;
23
23
  if (statement.condition) {
24
- let conditionPrecedingStatements;
25
24
  const tsCondition = statement.condition;
26
- [conditionPrecedingStatements, condition] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsCondition));
25
+ const { precedingStatements: conditionPrecedingStatements, result } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsCondition));
26
+ condition = result;
27
27
  // If condition has preceding statements, ensure they are executed every iteration by using the form:
28
28
  //
29
29
  // while true do
@@ -40,7 +40,7 @@ function transformForInitializer(context, initializer, block) {
40
40
  // Declaration of new variable
41
41
  const binding = getVariableDeclarationBinding(context, initializer);
42
42
  if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) {
43
- const [precedingStatements, bindings] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, binding, valueVariable));
43
+ const { precedingStatements, result: bindings } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, variable_declaration_1.transformBindingPattern)(context, binding, valueVariable));
44
44
  block.statements.unshift(...precedingStatements, ...bindings);
45
45
  }
46
46
  else {
@@ -99,7 +99,7 @@ function transformOptionalChainWithCapture(context, tsNode, thisValueCapture, is
99
99
  // transform right expression first to check if thisValue capture is needed
100
100
  // capture and return thisValue if requested from outside
101
101
  let returnThisValue;
102
- const [rightPrecedingStatements, rightExpression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
102
+ const { precedingStatements: rightPrecedingStatements, result: rightExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
103
103
  if (!thisValueCapture) {
104
104
  return context.transformExpression(tsRightExpression);
105
105
  }
@@ -113,7 +113,7 @@ function transformOptionalChainWithCapture(context, tsNode, thisValueCapture, is
113
113
  let capturedThisValue;
114
114
  const optionalContinuationData = getOptionalContinuationData(tsTemp);
115
115
  const rightContextualCall = optionalContinuationData === null || optionalContinuationData === void 0 ? void 0 : optionalContinuationData.contextualCall;
116
- const [leftPrecedingStatements, leftExpression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
116
+ const { precedingStatements: leftPrecedingStatements, result: leftExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
117
117
  let result;
118
118
  if (rightContextualCall) {
119
119
  ({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture(context, tsLeftExpression, leftThisValueTemp));
@@ -15,7 +15,7 @@ const transformSourceFileNode = (node, context) => {
15
15
  const [statement] = node.statements;
16
16
  if (statement) {
17
17
  (0, utils_1.assert)(ts.isExpressionStatement(statement));
18
- const [precedingStatements, expression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
18
+ const { precedingStatements, result: expression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(statement.expression));
19
19
  statements.push(...precedingStatements);
20
20
  statements.push(lua.createReturnStatement([expression]));
21
21
  }
@@ -25,18 +25,21 @@ const createOrExpression = (context, left, right, rightPrecedingStatements) => {
25
25
  return (0, binary_expression_1.createShortCircuitBinaryExpressionPrecedingStatements)(context, left, right, rightPrecedingStatements, ts.SyntaxKind.BarBarToken);
26
26
  }
27
27
  else {
28
- return [rightPrecedingStatements, lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator)];
28
+ return {
29
+ precedingStatements: rightPrecedingStatements,
30
+ result: lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator),
31
+ };
29
32
  }
30
33
  };
31
34
  const coalesceCondition = (condition, conditionPrecedingStatements, switchVariable, expression, context) => {
32
- const [precedingStatements, transformedExpression] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression));
35
+ const { precedingStatements, result: transformedExpression } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(expression));
33
36
  // Coalesce skipped statements
34
37
  const comparison = lua.createBinaryExpression(switchVariable, transformedExpression, lua.SyntaxKind.EqualityOperator);
35
38
  if (condition) {
36
39
  return createOrExpression(context, condition, comparison, precedingStatements);
37
40
  }
38
41
  // Next condition
39
- return [[...conditionPrecedingStatements, ...precedingStatements], comparison];
42
+ return { precedingStatements: [...conditionPrecedingStatements, ...precedingStatements], result: comparison };
40
43
  };
41
44
  const transformSwitchStatement = (statement, context) => {
42
45
  const scope = context.pushScope(scope_1.ScopeType.Switch);
@@ -77,7 +80,9 @@ const transformSwitchStatement = (statement, context) => {
77
80
  }
78
81
  // Compute the condition for the if statement
79
82
  if (!ts.isDefaultClause(clause)) {
80
- [conditionPrecedingStatements, condition] = coalesceCondition(condition, conditionPrecedingStatements, switchVariable, clause.expression, context);
83
+ const { precedingStatements, result } = coalesceCondition(condition, conditionPrecedingStatements, switchVariable, clause.expression, context);
84
+ conditionPrecedingStatements = precedingStatements;
85
+ condition = result;
81
86
  // Skip empty clauses unless final clause (i.e side-effects)
82
87
  if (i !== clauses.length - 1 && clause.statements.length === 0)
83
88
  continue;
@@ -86,7 +91,9 @@ const transformSwitchStatement = (statement, context) => {
86
91
  statements.push(...conditionPrecedingStatements, lua.createVariableDeclarationStatement(conditionVariable, condition));
87
92
  }
88
93
  else {
89
- [conditionPrecedingStatements, condition] = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
94
+ const { precedingStatements, result } = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
95
+ conditionPrecedingStatements = precedingStatements;
96
+ condition = result;
90
97
  statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
91
98
  }
92
99
  isInitialCondition = false;
@@ -104,7 +111,9 @@ const transformSwitchStatement = (statement, context) => {
104
111
  if (i === clauses.length - 1) {
105
112
  // Evaluate the final condition that we may be skipping
106
113
  if (condition) {
107
- [conditionPrecedingStatements, condition] = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
114
+ const { precedingStatements, result } = createOrExpression(context, conditionVariable, condition, conditionPrecedingStatements);
115
+ conditionPrecedingStatements = precedingStatements;
116
+ condition = result;
108
117
  statements.push(...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition));
109
118
  }
110
119
  continue;
@@ -43,7 +43,7 @@ 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
- const [precedingStatements, result] = (0, binary_expression_1.transformBinaryOperation)(context, typeCall, comparedExpression, [], operator, node);
46
+ const { precedingStatements, result } = (0, binary_expression_1.transformBinaryOperation)(context, typeCall, comparedExpression, [], operator, node);
47
47
  context.addPrecedingStatements(precedingStatements);
48
48
  return result;
49
49
  }
@@ -61,7 +61,7 @@ function transformBindingPattern(context, pattern, table, propertyAccessStack =
61
61
  const variableName = (0, identifier_1.transformIdentifier)(context, element.name);
62
62
  // The field to extract
63
63
  const elementName = (_a = element.propertyName) !== null && _a !== void 0 ? _a : element.name;
64
- const [precedingStatements, propertyName] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, literal_1.transformPropertyName)(context, elementName));
64
+ const { precedingStatements, result: propertyName } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, literal_1.transformPropertyName)(context, elementName));
65
65
  result.push(...precedingStatements); // Keep property's preceding statements in order
66
66
  let expression;
67
67
  if (element.dotDotDotToken) {
@@ -101,7 +101,7 @@ function transformBindingPattern(context, pattern, table, propertyAccessStack =
101
101
  if (element.initializer) {
102
102
  const identifier = (0, export_1.addExportToIdentifier)(context, variableName);
103
103
  const tsInitializer = element.initializer;
104
- const [initializerPrecedingStatements, initializer] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsInitializer));
104
+ const { precedingStatements: initializerPrecedingStatements, result: initializer } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => context.transformExpression(tsInitializer));
105
105
  result.push(lua.createIfStatement(lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), lua.createBlock([
106
106
  ...initializerPrecedingStatements,
107
107
  lua.createAssignmentStatement(identifier, initializer),
@@ -124,7 +124,7 @@ function transformBindingVariableDeclaration(context, bindingPattern, initialize
124
124
  if ((0, multi_1.isMultiReturnCall)(context, initializer)) {
125
125
  expression = (0, lua_ast_1.wrapInTable)(expression);
126
126
  }
127
- const [moveStatements, movedExpr] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, expression_list_1.moveToPrecedingTemp)(context, expression, initializer));
127
+ const { precedingStatements: moveStatements, result: movedExpr } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, expression_list_1.moveToPrecedingTemp)(context, expression, initializer));
128
128
  statements.push(...moveStatements);
129
129
  table = movedExpr;
130
130
  }
@@ -7,7 +7,7 @@ export interface TranspiledFile {
7
7
  declaration?: string;
8
8
  declarationMap?: string;
9
9
  }
10
- export declare function createEmitOutputCollector(): {
10
+ export declare function createEmitOutputCollector(luaExtension?: string): {
11
11
  writeFile: ts.WriteFileCallback;
12
12
  files: TranspiledFile[];
13
13
  };
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createEmitOutputCollector = void 0;
4
4
  const utils_1 = require("../utils");
5
- function createEmitOutputCollector() {
5
+ function createEmitOutputCollector(luaExtension = ".lua") {
6
6
  const files = [];
7
7
  const writeFile = (fileName, data, _bom, _onError, sourceFiles = []) => {
8
8
  let file = files.find(f => (0, utils_1.intersection)(f.sourceFiles, sourceFiles).length > 0);
@@ -13,10 +13,10 @@ function createEmitOutputCollector() {
13
13
  else {
14
14
  file.sourceFiles = (0, utils_1.union)(file.sourceFiles, sourceFiles);
15
15
  }
16
- if (fileName.endsWith(".lua")) {
16
+ if (fileName.endsWith(luaExtension)) {
17
17
  file.lua = data;
18
18
  }
19
- else if (fileName.endsWith(".lua.map")) {
19
+ else if (fileName.endsWith(`${luaExtension}.map`)) {
20
20
  file.luaSourceMap = data;
21
21
  }
22
22
  else if (fileName.endsWith(".js")) {
@@ -15,6 +15,7 @@ const resolver = resolve.ResolverFactory.createResolver({
15
15
  enforceExtension: true,
16
16
  fileSystem: { ...new resolve.CachedInputFileSystem(fs) },
17
17
  useSyncFileSystemCalls: true,
18
+ conditionNames: ["require", "node", "tstl", "default"],
18
19
  symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection)
19
20
  });
20
21
  class ResolutionContext {
@@ -40,8 +41,8 @@ class ResolutionContext {
40
41
  // Remove @NoResolution prefix if not building in library mode
41
42
  if (!isBuildModeLibrary(this.program)) {
42
43
  const path = required.requirePath.replace("@NoResolution:", "");
43
- replaceRequireInCode(file, required, path);
44
- replaceRequireInSourceMap(file, required, path);
44
+ replaceRequireInCode(file, required, path, this.options.extension);
45
+ replaceRequireInSourceMap(file, required, path, this.options.extension);
45
46
  }
46
47
  // Skip
47
48
  continue;
@@ -72,8 +73,8 @@ class ResolutionContext {
72
73
  // Figure out resolved require path and dependency output path
73
74
  if (shouldRewriteRequires(dependencyPath, this.program)) {
74
75
  const resolvedRequire = (0, transpiler_1.getEmitPathRelativeToOutDir)(dependencyPath, this.program);
75
- replaceRequireInCode(file, required, resolvedRequire);
76
- replaceRequireInSourceMap(file, required, resolvedRequire);
76
+ replaceRequireInCode(file, required, resolvedRequire, this.options.extension);
77
+ replaceRequireInSourceMap(file, required, resolvedRequire, this.options.extension);
77
78
  }
78
79
  }
79
80
  processDependency(dependencyPath) {
@@ -96,8 +97,8 @@ class ResolutionContext {
96
97
  }
97
98
  couldNotResolveImport(required, file) {
98
99
  const fallbackRequire = fallbackResolve(required, (0, transpiler_1.getSourceDir)(this.program), path.dirname(file.fileName));
99
- replaceRequireInCode(file, required, fallbackRequire);
100
- replaceRequireInSourceMap(file, required, fallbackRequire);
100
+ replaceRequireInCode(file, required, fallbackRequire, this.options.extension);
101
+ replaceRequireInSourceMap(file, required, fallbackRequire, this.options.extension);
101
102
  this.diagnostics.push((0, diagnostics_1.couldNotResolveRequire)(required.requirePath, path.relative((0, transpiler_1.getProjectRoot)(this.program), file.fileName)));
102
103
  }
103
104
  resolveDependencyPath(requiringFile, dependency) {
@@ -263,19 +264,27 @@ function shouldIncludeDependency(resolvedDependency, program) {
263
264
  function isBuildModeLibrary(program) {
264
265
  return program.getCompilerOptions().buildMode === CompilerOptions_1.BuildMode.Library;
265
266
  }
266
- function replaceRequireInCode(file, originalRequire, newRequire) {
267
- const requirePath = (0, utils_1.formatPathToLuaPath)(newRequire.replace(".lua", ""));
267
+ function replaceRequireInCode(file, originalRequire, newRequire, extension) {
268
+ const requirePath = requirePathForFile(newRequire, extension);
268
269
  file.code = file.code =
269
270
  file.code.substring(0, originalRequire.from) +
270
271
  `require("${requirePath}")` +
271
272
  file.code.substring(originalRequire.to + 1);
272
273
  }
273
- function replaceRequireInSourceMap(file, originalRequire, newRequire) {
274
- const requirePath = (0, utils_1.formatPathToLuaPath)(newRequire.replace(".lua", ""));
274
+ function replaceRequireInSourceMap(file, originalRequire, newRequire, extension) {
275
+ const requirePath = requirePathForFile(newRequire, extension);
275
276
  if (file.sourceMapNode) {
276
277
  replaceInSourceMap(file.sourceMapNode, file.sourceMapNode, `"${originalRequire.requirePath}"`, `"${requirePath}"`);
277
278
  }
278
279
  }
280
+ function requirePathForFile(filePath, extension = ".lua") {
281
+ if (filePath.endsWith(extension)) {
282
+ return (0, utils_1.formatPathToLuaPath)(filePath.substring(0, filePath.length - extension.length));
283
+ }
284
+ else {
285
+ return (0, utils_1.formatPathToLuaPath)(filePath);
286
+ }
287
+ }
279
288
  function replaceInSourceMap(node, parent, require, resolvedRequire) {
280
289
  if ((!node.children || node.children.length === 0) && node.toString() === require) {
281
290
  parent.children = [new source_map_1.SourceNode(node.line, node.column, node.source, [resolvedRequire])];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typescript-to-lua",
3
- "version": "1.12.1",
3
+ "version": "1.13.0",
4
4
  "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",
5
5
  "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",
6
6
  "homepage": "https://typescripttolua.github.io/",