typescript-to-lua 1.12.1 → 1.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/lualib/5.0/Await.lua +5 -11
  2. package/dist/lualib/5.0/Decorate.lua +1 -1
  3. package/dist/lualib/5.0/Error.lua +12 -18
  4. package/dist/lualib/5.0/Map.lua +3 -3
  5. package/dist/lualib/5.0/MathModf.lua +1 -7
  6. package/dist/lualib/5.0/ObjectDefineProperty.lua +21 -27
  7. package/dist/lualib/5.0/ParseFloat.lua +2 -8
  8. package/dist/lualib/5.0/ParseInt.lua +9 -21
  9. package/dist/lualib/5.0/Set.lua +3 -3
  10. package/dist/lualib/5.0/SetDescriptor.lua +2 -2
  11. package/dist/lualib/5.0/SourceMapTraceBack.lua +4 -4
  12. package/dist/lualib/5.0/StringReplace.lua +1 -7
  13. package/dist/lualib/5.0/SymbolRegistry.lua +1 -0
  14. package/dist/lualib/5.0/lualib_bundle.lua +65 -112
  15. package/dist/lualib/universal/Await.lua +5 -11
  16. package/dist/lualib/universal/Decorate.lua +1 -1
  17. package/dist/lualib/universal/Error.lua +12 -18
  18. package/dist/lualib/universal/Map.lua +3 -3
  19. package/dist/lualib/universal/ObjectDefineProperty.lua +21 -27
  20. package/dist/lualib/universal/ParseFloat.lua +2 -8
  21. package/dist/lualib/universal/ParseInt.lua +3 -15
  22. package/dist/lualib/universal/Set.lua +3 -3
  23. package/dist/lualib/universal/SetDescriptor.lua +2 -2
  24. package/dist/lualib/universal/SourceMapTraceBack.lua +5 -5
  25. package/dist/lualib/universal/StringReplace.lua +1 -7
  26. package/dist/lualib/universal/SymbolRegistry.lua +1 -0
  27. package/dist/lualib/universal/lualib_bundle.lua +59 -100
  28. package/dist/transformation/utils/preceding-statements.d.ts +5 -1
  29. package/dist/transformation/utils/preceding-statements.js +1 -1
  30. package/dist/transformation/visitors/binary-expression/assignments.js +3 -3
  31. package/dist/transformation/visitors/binary-expression/compound.d.ts +0 -7
  32. package/dist/transformation/visitors/binary-expression/compound.js +40 -22
  33. package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +5 -5
  34. package/dist/transformation/visitors/binary-expression/index.d.ts +3 -2
  35. package/dist/transformation/visitors/binary-expression/index.js +12 -13
  36. package/dist/transformation/visitors/call.js +2 -2
  37. package/dist/transformation/visitors/class/index.js +1 -1
  38. package/dist/transformation/visitors/class/members/fields.js +1 -1
  39. package/dist/transformation/visitors/conditional.js +10 -10
  40. package/dist/transformation/visitors/expression-list.js +1 -1
  41. package/dist/transformation/visitors/function.js +2 -2
  42. package/dist/transformation/visitors/loops/do-while.js +2 -2
  43. package/dist/transformation/visitors/loops/for.js +2 -2
  44. package/dist/transformation/visitors/loops/utils.js +1 -1
  45. package/dist/transformation/visitors/optional-chaining.js +2 -2
  46. package/dist/transformation/visitors/sourceFile.js +1 -1
  47. package/dist/transformation/visitors/switch.js +15 -6
  48. package/dist/transformation/visitors/typeof.js +1 -1
  49. package/dist/transformation/visitors/variable-declaration.js +3 -3
  50. package/dist/transpilation/output-collector.d.ts +1 -1
  51. package/dist/transpilation/output-collector.js +3 -3
  52. package/dist/transpilation/resolve.js +22 -10
  53. package/package.json +7 -7
@@ -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,30 @@ 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 (!extension.startsWith(".")) {
282
+ extension = `.${extension}`;
283
+ }
284
+ if (filePath.endsWith(extension)) {
285
+ return (0, utils_1.formatPathToLuaPath)(filePath.substring(0, filePath.length - extension.length));
286
+ }
287
+ else {
288
+ return (0, utils_1.formatPathToLuaPath)(filePath);
289
+ }
290
+ }
279
291
  function replaceInSourceMap(node, parent, require, resolvedRequire) {
280
292
  if ((!node.children || node.children.length === 0) && node.toString() === require) {
281
293
  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.1",
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/",
@@ -56,15 +56,15 @@
56
56
  "@types/jest": "^27.5.2",
57
57
  "@types/node": "^13.7.7",
58
58
  "@types/resolve": "1.14.0",
59
- "@typescript-eslint/eslint-plugin": "^5.36.1",
60
- "@typescript-eslint/parser": "^5.36.1",
61
- "eslint": "^8.23.0",
62
- "eslint-plugin-import": "^2.26.0",
63
- "eslint-plugin-jest": "^26.8.7",
59
+ "@typescript-eslint/eslint-plugin": "^5.52.0",
60
+ "@typescript-eslint/parser": "^5.52.0",
61
+ "eslint": "^8.34.0",
62
+ "eslint-plugin-import": "^2.27.5",
63
+ "eslint-plugin-jest": "^26.9.0",
64
64
  "fs-extra": "^8.1.0",
65
65
  "javascript-stringify": "^2.0.1",
66
66
  "jest": "^28.1.3",
67
- "jest-circus": "^29.0.1",
67
+ "jest-circus": "^29.4.2",
68
68
  "lua-types": "^2.13.0",
69
69
  "lua-wasm-bindings": "^0.3.1",
70
70
  "prettier": "^2.3.2",