typescript-to-lua 1.12.0 → 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 (62) hide show
  1. package/dist/CompilerOptions.d.ts +2 -1
  2. package/dist/CompilerOptions.js +1 -0
  3. package/dist/LuaLib.d.ts +4 -0
  4. package/dist/LuaLib.js +69 -19
  5. package/dist/LuaPrinter.js +2 -1
  6. package/dist/lualib/5.0/ArraySlice.lua +2 -10
  7. package/dist/lualib/5.0/ArraySplice.lua +1 -5
  8. package/dist/lualib/5.0/ParseFloat.lua +1 -5
  9. package/dist/lualib/5.0/StringCharCodeAt.lua +1 -5
  10. package/dist/lualib/5.0/lualib_bundle.lua +5 -25
  11. package/dist/lualib/universal/ArraySlice.lua +2 -10
  12. package/dist/lualib/universal/ArraySplice.lua +1 -5
  13. package/dist/lualib/universal/ParseFloat.lua +1 -5
  14. package/dist/lualib/universal/SparseArraySpread.lua +1 -5
  15. package/dist/lualib/universal/StringCharCodeAt.lua +1 -5
  16. package/dist/lualib/universal/lualib_bundle.lua +6 -30
  17. package/dist/lualib-build/plugin.js +1 -1
  18. package/dist/transformation/builtins/array.js +1 -1
  19. package/dist/transformation/utils/diagnostics.d.ts +6 -0
  20. package/dist/transformation/utils/diagnostics.js +3 -1
  21. package/dist/transformation/utils/language-extensions.d.ts +4 -0
  22. package/dist/transformation/utils/language-extensions.js +66 -1
  23. package/dist/transformation/utils/preceding-statements.d.ts +5 -1
  24. package/dist/transformation/utils/preceding-statements.js +1 -1
  25. package/dist/transformation/utils/typescript/index.d.ts +1 -0
  26. package/dist/transformation/utils/typescript/index.js +5 -1
  27. package/dist/transformation/utils/typescript/types.js +0 -3
  28. package/dist/transformation/visitors/binary-expression/assignments.js +3 -3
  29. package/dist/transformation/visitors/binary-expression/compound.d.ts +0 -7
  30. package/dist/transformation/visitors/binary-expression/compound.js +40 -22
  31. package/dist/transformation/visitors/binary-expression/destructuring-assignments.js +5 -5
  32. package/dist/transformation/visitors/binary-expression/index.d.ts +3 -2
  33. package/dist/transformation/visitors/binary-expression/index.js +12 -13
  34. package/dist/transformation/visitors/call.js +2 -2
  35. package/dist/transformation/visitors/class/index.js +1 -1
  36. package/dist/transformation/visitors/class/members/fields.js +1 -1
  37. package/dist/transformation/visitors/conditional.js +10 -10
  38. package/dist/transformation/visitors/expression-list.js +1 -1
  39. package/dist/transformation/visitors/expression-statement.d.ts +2 -2
  40. package/dist/transformation/visitors/expression-statement.js +4 -5
  41. package/dist/transformation/visitors/function.js +2 -2
  42. package/dist/transformation/visitors/identifier.js +3 -1
  43. package/dist/transformation/visitors/language-extensions/operators.js +9 -15
  44. package/dist/transformation/visitors/language-extensions/table.d.ts +2 -4
  45. package/dist/transformation/visitors/language-extensions/table.js +32 -38
  46. package/dist/transformation/visitors/loops/do-while.js +2 -2
  47. package/dist/transformation/visitors/loops/for.js +2 -2
  48. package/dist/transformation/visitors/loops/utils.js +1 -1
  49. package/dist/transformation/visitors/optional-chaining.d.ts +2 -1
  50. package/dist/transformation/visitors/optional-chaining.js +79 -33
  51. package/dist/transformation/visitors/sourceFile.js +1 -1
  52. package/dist/transformation/visitors/switch.js +15 -6
  53. package/dist/transformation/visitors/typeof.js +1 -1
  54. package/dist/transformation/visitors/variable-declaration.js +3 -3
  55. package/dist/transformation/visitors/void.js +1 -1
  56. package/dist/transpilation/diagnostics.js +1 -1
  57. package/dist/transpilation/output-collector.d.ts +1 -1
  58. package/dist/transpilation/output-collector.js +3 -3
  59. package/dist/transpilation/resolve.js +19 -10
  60. package/dist/transpilation/transpiler.d.ts +1 -0
  61. package/dist/transpilation/transpiler.js +13 -3
  62. package/package.json +1 -1
@@ -39,7 +39,8 @@ export type CompilerOptions = OmitIndexSignature<ts.CompilerOptions> & TypeScrip
39
39
  export declare enum LuaLibImportKind {
40
40
  None = "none",
41
41
  Inline = "inline",
42
- Require = "require"
42
+ Require = "require",
43
+ RequireMinimal = "require-minimal"
43
44
  }
44
45
  export declare enum LuaTarget {
45
46
  Universal = "universal",
@@ -8,6 +8,7 @@ var LuaLibImportKind;
8
8
  LuaLibImportKind["None"] = "none";
9
9
  LuaLibImportKind["Inline"] = "inline";
10
10
  LuaLibImportKind["Require"] = "require";
11
+ LuaLibImportKind["RequireMinimal"] = "require-minimal";
11
12
  })(LuaLibImportKind = exports.LuaLibImportKind || (exports.LuaLibImportKind = {}));
12
13
  var LuaTarget;
13
14
  (function (LuaTarget) {
package/dist/LuaLib.d.ts CHANGED
@@ -110,8 +110,12 @@ export type LuaLibModulesInfo = Record<LuaLibFeature, LuaLibFeatureInfo>;
110
110
  export declare function resolveLuaLibDir(luaTarget: LuaTarget): string;
111
111
  export declare const luaLibModulesInfoFileName = "lualib_module_info.json";
112
112
  export declare function getLuaLibModulesInfo(luaTarget: LuaTarget, emitHost: EmitHost): LuaLibModulesInfo;
113
+ export declare function getLuaLibExportToFeatureMap(luaTarget: LuaTarget, emitHost: EmitHost): ReadonlyMap<string, LuaLibFeature>;
113
114
  export declare function readLuaLibFeature(feature: LuaLibFeature, luaTarget: LuaTarget, emitHost: EmitHost): string;
114
115
  export declare function resolveRecursiveLualibFeatures(features: Iterable<LuaLibFeature>, luaTarget: LuaTarget, emitHost: EmitHost, luaLibModulesInfo?: LuaLibModulesInfo): LuaLibFeature[];
115
116
  export declare function loadInlineLualibFeatures(features: Iterable<LuaLibFeature>, luaTarget: LuaTarget, emitHost: EmitHost): string;
116
117
  export declare function loadImportedLualibFeatures(features: Iterable<LuaLibFeature>, luaTarget: LuaTarget, emitHost: EmitHost): lua.Statement[];
117
118
  export declare function getLuaLibBundle(luaTarget: LuaTarget, emitHost: EmitHost): string;
119
+ export declare function getLualibBundleReturn(exportedValues: string[]): string;
120
+ export declare function buildMinimalLualibBundle(features: Iterable<LuaLibFeature>, luaTarget: LuaTarget, emitHost: EmitHost): string;
121
+ export declare function findUsedLualibFeatures(luaTarget: LuaTarget, emitHost: EmitHost, luaContents: string[]): Set<LuaLibFeature>;
package/dist/LuaLib.js CHANGED
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLuaLibBundle = exports.loadImportedLualibFeatures = exports.loadInlineLualibFeatures = exports.resolveRecursiveLualibFeatures = exports.readLuaLibFeature = exports.getLuaLibModulesInfo = exports.luaLibModulesInfoFileName = exports.resolveLuaLibDir = exports.LuaLibFeature = void 0;
3
+ exports.findUsedLualibFeatures = exports.buildMinimalLualibBundle = exports.getLualibBundleReturn = exports.getLuaLibBundle = exports.loadImportedLualibFeatures = exports.loadInlineLualibFeatures = exports.resolveRecursiveLualibFeatures = exports.readLuaLibFeature = exports.getLuaLibExportToFeatureMap = exports.getLuaLibModulesInfo = exports.luaLibModulesInfoFileName = exports.resolveLuaLibDir = exports.LuaLibFeature = void 0;
4
4
  const path = require("path");
5
5
  const lua = require("./LuaAST");
6
6
  const CompilerOptions_1 = require("./CompilerOptions");
7
+ const utils_1 = require("./utils");
7
8
  var LuaLibFeature;
8
9
  (function (LuaLibFeature) {
9
10
  LuaLibFeature["ArrayConcat"] = "ArrayConcat";
@@ -114,26 +115,47 @@ exports.resolveLuaLibDir = resolveLuaLibDir;
114
115
  exports.luaLibModulesInfoFileName = "lualib_module_info.json";
115
116
  const luaLibModulesInfo = new Map();
116
117
  function getLuaLibModulesInfo(luaTarget, emitHost) {
117
- const lualibPath = path.join(resolveLuaLibDir(luaTarget), exports.luaLibModulesInfoFileName);
118
- if (!luaLibModulesInfo.has(lualibPath)) {
118
+ if (!luaLibModulesInfo.has(luaTarget)) {
119
+ const lualibPath = path.join(resolveLuaLibDir(luaTarget), exports.luaLibModulesInfoFileName);
119
120
  const result = emitHost.readFile(lualibPath);
120
121
  if (result !== undefined) {
121
- luaLibModulesInfo.set(lualibPath, JSON.parse(result));
122
+ luaLibModulesInfo.set(luaTarget, JSON.parse(result));
122
123
  }
123
124
  else {
124
125
  throw new Error(`Could not load lualib dependencies from '${lualibPath}'`);
125
126
  }
126
127
  }
127
- return luaLibModulesInfo.get(lualibPath);
128
+ return luaLibModulesInfo.get(luaTarget);
128
129
  }
129
130
  exports.getLuaLibModulesInfo = getLuaLibModulesInfo;
131
+ // This caches the names of lualib exports to their LuaLibFeature, avoiding a linear search for every lookup
132
+ const lualibExportToFeature = new Map();
133
+ function getLuaLibExportToFeatureMap(luaTarget, emitHost) {
134
+ if (!lualibExportToFeature.has(luaTarget)) {
135
+ const luaLibModulesInfo = getLuaLibModulesInfo(luaTarget, emitHost);
136
+ const map = new Map();
137
+ for (const [feature, info] of Object.entries(luaLibModulesInfo)) {
138
+ for (const exportName of info.exports) {
139
+ map.set(exportName, feature);
140
+ }
141
+ }
142
+ lualibExportToFeature.set(luaTarget, map);
143
+ }
144
+ return lualibExportToFeature.get(luaTarget);
145
+ }
146
+ exports.getLuaLibExportToFeatureMap = getLuaLibExportToFeatureMap;
147
+ const lualibFeatureCache = new Map();
130
148
  function readLuaLibFeature(feature, luaTarget, emitHost) {
131
- const featurePath = path.join(resolveLuaLibDir(luaTarget), `${feature}.lua`);
132
- const luaLibFeature = emitHost.readFile(featurePath);
133
- if (luaLibFeature === undefined) {
134
- throw new Error(`Could not load lualib feature from '${featurePath}'`);
149
+ const featureMap = (0, utils_1.getOrUpdate)(lualibFeatureCache, luaTarget, () => new Map());
150
+ if (!featureMap.has(feature)) {
151
+ const featurePath = path.join(resolveLuaLibDir(luaTarget), `${feature}.lua`);
152
+ const luaLibFeature = emitHost.readFile(featurePath);
153
+ if (luaLibFeature === undefined) {
154
+ throw new Error(`Could not load lualib feature from '${featurePath}'`);
155
+ }
156
+ featureMap.set(feature, luaLibFeature);
135
157
  }
136
- return luaLibFeature;
158
+ return featureMap.get(feature);
137
159
  }
138
160
  exports.readLuaLibFeature = readLuaLibFeature;
139
161
  function resolveRecursiveLualibFeatures(features, luaTarget, emitHost, luaLibModulesInfo = getLuaLibModulesInfo(luaTarget, emitHost)) {
@@ -157,23 +179,20 @@ function resolveRecursiveLualibFeatures(features, luaTarget, emitHost, luaLibMod
157
179
  }
158
180
  exports.resolveRecursiveLualibFeatures = resolveRecursiveLualibFeatures;
159
181
  function loadInlineLualibFeatures(features, luaTarget, emitHost) {
160
- let result = "";
161
- for (const feature of resolveRecursiveLualibFeatures(features, luaTarget, emitHost)) {
162
- const luaLibFeature = readLuaLibFeature(feature, luaTarget, emitHost);
163
- result += luaLibFeature + "\n";
164
- }
165
- return result;
182
+ return resolveRecursiveLualibFeatures(features, luaTarget, emitHost)
183
+ .map(feature => readLuaLibFeature(feature, luaTarget, emitHost))
184
+ .join("\n");
166
185
  }
167
186
  exports.loadInlineLualibFeatures = loadInlineLualibFeatures;
168
187
  function loadImportedLualibFeatures(features, luaTarget, emitHost) {
169
188
  const luaLibModuleInfo = getLuaLibModulesInfo(luaTarget, emitHost);
170
189
  const imports = Array.from(features).flatMap(feature => luaLibModuleInfo[feature].exports);
171
- const requireCall = lua.createCallExpression(lua.createIdentifier("require"), [
172
- lua.createStringLiteral("lualib_bundle"),
173
- ]);
174
190
  if (imports.length === 0) {
175
191
  return [];
176
192
  }
193
+ const requireCall = lua.createCallExpression(lua.createIdentifier("require"), [
194
+ lua.createStringLiteral("lualib_bundle"),
195
+ ]);
177
196
  const luaLibId = lua.createIdentifier("____lualib");
178
197
  const importStatement = lua.createVariableDeclarationStatement(luaLibId, requireCall);
179
198
  const statements = [importStatement];
@@ -199,4 +218,35 @@ function getLuaLibBundle(luaTarget, emitHost) {
199
218
  return luaLibBundleContent.get(lualibPath);
200
219
  }
201
220
  exports.getLuaLibBundle = getLuaLibBundle;
221
+ function getLualibBundleReturn(exportedValues) {
222
+ return `\nreturn {\n${exportedValues.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`;
223
+ }
224
+ exports.getLualibBundleReturn = getLualibBundleReturn;
225
+ function buildMinimalLualibBundle(features, luaTarget, emitHost) {
226
+ const code = loadInlineLualibFeatures(features, luaTarget, emitHost);
227
+ const moduleInfo = getLuaLibModulesInfo(luaTarget, emitHost);
228
+ const exports = Array.from(features).flatMap(feature => moduleInfo[feature].exports);
229
+ return code + getLualibBundleReturn(exports);
230
+ }
231
+ exports.buildMinimalLualibBundle = buildMinimalLualibBundle;
232
+ function findUsedLualibFeatures(luaTarget, emitHost, luaContents) {
233
+ const features = new Set();
234
+ const exportToFeatureMap = getLuaLibExportToFeatureMap(luaTarget, emitHost);
235
+ for (const lua of luaContents) {
236
+ const regex = /^local (\w+) = ____lualib\.(\w+)$/gm;
237
+ while (true) {
238
+ const match = regex.exec(lua);
239
+ if (!match)
240
+ break;
241
+ const [, localName, exportName] = match;
242
+ if (localName !== exportName)
243
+ continue;
244
+ const feature = exportToFeatureMap.get(exportName);
245
+ if (feature)
246
+ features.add(feature);
247
+ }
248
+ }
249
+ return features;
250
+ }
251
+ exports.findUsedLualibFeatures = findUsedLualibFeatures;
202
252
  //# sourceMappingURL=LuaLib.js.map
@@ -135,7 +135,8 @@ class LuaPrinter {
135
135
  }
136
136
  const luaTarget = (_a = this.options.luaTarget) !== null && _a !== void 0 ? _a : CompilerOptions_1.LuaTarget.Universal;
137
137
  const luaLibImport = (_b = this.options.luaLibImport) !== null && _b !== void 0 ? _b : CompilerOptions_1.LuaLibImportKind.Require;
138
- if (luaLibImport === CompilerOptions_1.LuaLibImportKind.Require && file.luaLibFeatures.size > 0) {
138
+ if ((luaLibImport === CompilerOptions_1.LuaLibImportKind.Require || luaLibImport === CompilerOptions_1.LuaLibImportKind.RequireMinimal) &&
139
+ file.luaLibFeatures.size > 0) {
139
140
  // Import lualib features
140
141
  sourceChunks = this.printStatementArray((0, LuaLib_1.loadImportedLualibFeatures)(file.luaLibFeatures, luaTarget, this.emitHost));
141
142
  }
@@ -1,10 +1,6 @@
1
1
  local function __TS__ArraySlice(self, first, last)
2
2
  local len = table.getn(self)
3
- local ____first_0 = first
4
- if ____first_0 == nil then
5
- ____first_0 = 0
6
- end
7
- first = ____first_0
3
+ first = first or 0
8
4
  if first < 0 then
9
5
  first = len + first
10
6
  if first < 0 then
@@ -15,11 +11,7 @@ local function __TS__ArraySlice(self, first, last)
15
11
  first = len
16
12
  end
17
13
  end
18
- local ____last_1 = last
19
- if ____last_1 == nil then
20
- ____last_1 = len
21
- end
22
- last = ____last_1
14
+ last = last or len
23
15
  if last < 0 then
24
16
  last = len + last
25
17
  if last < 0 then
@@ -22,11 +22,7 @@ local function __TS__ArraySplice(self, ...)
22
22
  elseif actualArgumentCount == 1 then
23
23
  actualDeleteCount = len - start
24
24
  else
25
- local ____deleteCount_0 = deleteCount
26
- if ____deleteCount_0 == nil then
27
- ____deleteCount_0 = 0
28
- end
29
- actualDeleteCount = ____deleteCount_0
25
+ actualDeleteCount = deleteCount or 0
30
26
  if actualDeleteCount < 0 then
31
27
  actualDeleteCount = 0
32
28
  end
@@ -10,9 +10,5 @@ local function __TS__ParseFloat(numberString)
10
10
  return ____temp_0
11
11
  end
12
12
  local number = tonumber(__TS__Match(numberString, "^%s*(-?%d+%.?%d*)"))
13
- local ____number_1 = number
14
- if ____number_1 == nil then
15
- ____number_1 = 0 / 0
16
- end
17
- return ____number_1
13
+ return number or 0 / 0
18
14
  end
@@ -5,9 +5,5 @@ local function __TS__StringCharCodeAt(self, index)
5
5
  if index < 0 then
6
6
  return 0 / 0
7
7
  end
8
- local ____string_byte_result_0 = string.byte(self, index + 1)
9
- if ____string_byte_result_0 == nil then
10
- ____string_byte_result_0 = 0 / 0
11
- end
12
- return ____string_byte_result_0
8
+ return string.byte(self, index + 1) or 0 / 0
13
9
  end
@@ -350,11 +350,7 @@ end
350
350
 
351
351
  local function __TS__ArraySlice(self, first, last)
352
352
  local len = table.getn(self)
353
- local ____first_0 = first
354
- if ____first_0 == nil then
355
- ____first_0 = 0
356
- end
357
- first = ____first_0
353
+ first = first or 0
358
354
  if first < 0 then
359
355
  first = len + first
360
356
  if first < 0 then
@@ -365,11 +361,7 @@ local function __TS__ArraySlice(self, first, last)
365
361
  first = len
366
362
  end
367
363
  end
368
- local ____last_1 = last
369
- if ____last_1 == nil then
370
- ____last_1 = len
371
- end
372
- last = ____last_1
364
+ last = last or len
373
365
  if last < 0 then
374
366
  last = len + last
375
367
  if last < 0 then
@@ -425,11 +417,7 @@ local function __TS__ArraySplice(self, ...)
425
417
  elseif actualArgumentCount == 1 then
426
418
  actualDeleteCount = len - start
427
419
  else
428
- local ____deleteCount_0 = deleteCount
429
- if ____deleteCount_0 == nil then
430
- ____deleteCount_0 = 0
431
- end
432
- actualDeleteCount = ____deleteCount_0
420
+ actualDeleteCount = deleteCount or 0
433
421
  if actualDeleteCount < 0 then
434
422
  actualDeleteCount = 0
435
423
  end
@@ -1661,11 +1649,7 @@ local function __TS__ParseFloat(numberString)
1661
1649
  return ____temp_0
1662
1650
  end
1663
1651
  local number = tonumber(__TS__Match(numberString, "^%s*(-?%d+%.?%d*)"))
1664
- local ____number_1 = number
1665
- if ____number_1 == nil then
1666
- ____number_1 = 0 / 0
1667
- end
1668
- return ____number_1
1652
+ return number or 0 / 0
1669
1653
  end
1670
1654
 
1671
1655
  local function __TS__StringSubstring(self, start, ____end)
@@ -2230,11 +2214,7 @@ local function __TS__StringCharCodeAt(self, index)
2230
2214
  if index < 0 then
2231
2215
  return 0 / 0
2232
2216
  end
2233
- local ____string_byte_result_0 = string.byte(self, index + 1)
2234
- if ____string_byte_result_0 == nil then
2235
- ____string_byte_result_0 = 0 / 0
2236
- end
2237
- return ____string_byte_result_0
2217
+ return string.byte(self, index + 1) or 0 / 0
2238
2218
  end
2239
2219
 
2240
2220
  local function __TS__StringEndsWith(self, searchString, endPosition)
@@ -1,10 +1,6 @@
1
1
  local function __TS__ArraySlice(self, first, last)
2
2
  local len = #self
3
- local ____first_0 = first
4
- if ____first_0 == nil then
5
- ____first_0 = 0
6
- end
7
- first = ____first_0
3
+ first = first or 0
8
4
  if first < 0 then
9
5
  first = len + first
10
6
  if first < 0 then
@@ -15,11 +11,7 @@ local function __TS__ArraySlice(self, first, last)
15
11
  first = len
16
12
  end
17
13
  end
18
- local ____last_1 = last
19
- if ____last_1 == nil then
20
- ____last_1 = len
21
- end
22
- last = ____last_1
14
+ last = last or len
23
15
  if last < 0 then
24
16
  last = len + last
25
17
  if last < 0 then
@@ -22,11 +22,7 @@ local function __TS__ArraySplice(self, ...)
22
22
  elseif actualArgumentCount == 1 then
23
23
  actualDeleteCount = len - start
24
24
  else
25
- local ____deleteCount_0 = deleteCount
26
- if ____deleteCount_0 == nil then
27
- ____deleteCount_0 = 0
28
- end
29
- actualDeleteCount = ____deleteCount_0
25
+ actualDeleteCount = deleteCount or 0
30
26
  if actualDeleteCount < 0 then
31
27
  actualDeleteCount = 0
32
28
  end
@@ -10,9 +10,5 @@ local function __TS__ParseFloat(numberString)
10
10
  return ____temp_0
11
11
  end
12
12
  local number = tonumber(__TS__Match(numberString, "^%s*(-?%d+%.?%d*)"))
13
- local ____number_1 = number
14
- if ____number_1 == nil then
15
- ____number_1 = 0 / 0
16
- end
17
- return ____number_1
13
+ return number or 0 / 0
18
14
  end
@@ -1,8 +1,4 @@
1
1
  local function __TS__SparseArraySpread(sparseArray)
2
- local ____unpack_0 = unpack
3
- if ____unpack_0 == nil then
4
- ____unpack_0 = table.unpack
5
- end
6
- local _unpack = ____unpack_0
2
+ local _unpack = unpack or table.unpack
7
3
  return _unpack(sparseArray, 1, sparseArray.sparseLength)
8
4
  end
@@ -5,9 +5,5 @@ local function __TS__StringCharCodeAt(self, index)
5
5
  if index < 0 then
6
6
  return 0 / 0
7
7
  end
8
- local ____string_byte_result_0 = string.byte(self, index + 1)
9
- if ____string_byte_result_0 == nil then
10
- ____string_byte_result_0 = 0 / 0
11
- end
12
- return ____string_byte_result_0
8
+ return string.byte(self, index + 1) or 0 / 0
13
9
  end
@@ -349,11 +349,7 @@ end
349
349
 
350
350
  local function __TS__ArraySlice(self, first, last)
351
351
  local len = #self
352
- local ____first_0 = first
353
- if ____first_0 == nil then
354
- ____first_0 = 0
355
- end
356
- first = ____first_0
352
+ first = first or 0
357
353
  if first < 0 then
358
354
  first = len + first
359
355
  if first < 0 then
@@ -364,11 +360,7 @@ local function __TS__ArraySlice(self, first, last)
364
360
  first = len
365
361
  end
366
362
  end
367
- local ____last_1 = last
368
- if ____last_1 == nil then
369
- ____last_1 = len
370
- end
371
- last = ____last_1
363
+ last = last or len
372
364
  if last < 0 then
373
365
  last = len + last
374
366
  if last < 0 then
@@ -424,11 +416,7 @@ local function __TS__ArraySplice(self, ...)
424
416
  elseif actualArgumentCount == 1 then
425
417
  actualDeleteCount = len - start
426
418
  else
427
- local ____deleteCount_0 = deleteCount
428
- if ____deleteCount_0 == nil then
429
- ____deleteCount_0 = 0
430
- end
431
- actualDeleteCount = ____deleteCount_0
419
+ actualDeleteCount = deleteCount or 0
432
420
  if actualDeleteCount < 0 then
433
421
  actualDeleteCount = 0
434
422
  end
@@ -1597,11 +1585,7 @@ local function __TS__ParseFloat(numberString)
1597
1585
  return ____temp_0
1598
1586
  end
1599
1587
  local number = tonumber(__TS__Match(numberString, "^%s*(-?%d+%.?%d*)"))
1600
- local ____number_1 = number
1601
- if ____number_1 == nil then
1602
- ____number_1 = 0 / 0
1603
- end
1604
- return ____number_1
1588
+ return number or 0 / 0
1605
1589
  end
1606
1590
 
1607
1591
  local function __TS__StringSubstring(self, start, ____end)
@@ -1979,11 +1963,7 @@ local function __TS__SparseArrayPush(sparseArray, ...)
1979
1963
  end
1980
1964
 
1981
1965
  local function __TS__SparseArraySpread(sparseArray)
1982
- local ____unpack_0 = unpack
1983
- if ____unpack_0 == nil then
1984
- ____unpack_0 = table.unpack
1985
- end
1986
- local _unpack = ____unpack_0
1966
+ local _unpack = unpack or table.unpack
1987
1967
  return _unpack(sparseArray, 1, sparseArray.sparseLength)
1988
1968
  end
1989
1969
 
@@ -2165,11 +2145,7 @@ local function __TS__StringCharCodeAt(self, index)
2165
2145
  if index < 0 then
2166
2146
  return 0 / 0
2167
2147
  end
2168
- local ____string_byte_result_0 = string.byte(self, index + 1)
2169
- if ____string_byte_result_0 == nil then
2170
- ____string_byte_result_0 = 0 / 0
2171
- end
2172
- return ____string_byte_result_0
2148
+ return string.byte(self, index + 1) or 0 / 0
2173
2149
  end
2174
2150
 
2175
2151
  local function __TS__StringEndsWith(self, searchString, endPosition)
@@ -49,7 +49,7 @@ class LuaLibPlugin {
49
49
  // Concatenate lualib files into bundle with exports table and add lualib_bundle.lua to results
50
50
  let lualibBundle = orderedFeatures.map(f => exportedLualibFeatures.get(LuaLib_1.LuaLibFeature[f])).join("\n");
51
51
  const exports = allFeatures.flatMap(feature => luaLibModuleInfo[feature].exports);
52
- lualibBundle += `\nreturn {\n${exports.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`;
52
+ lualibBundle += (0, LuaLib_1.getLualibBundleReturn)(exports);
53
53
  result.push({ fileName: "lualib_bundle.lua", code: lualibBundle });
54
54
  return diagnostics;
55
55
  }
@@ -42,10 +42,10 @@ function createTableLengthExpression(context, expression, node) {
42
42
  * return (#array + 1)
43
43
  */
44
44
  function transformSingleElementArrayPush(context, node, caller, param) {
45
- const expressionIsUsed = !ts.isExpressionStatement((0, typescript_1.findFirstNonOuterParent)(node));
46
45
  const arrayIdentifier = lua.isIdentifier(caller) ? caller : (0, expression_list_1.moveToPrecedingTemp)(context, caller);
47
46
  // #array + 1
48
47
  let lengthExpression = lua.createBinaryExpression(createTableLengthExpression(context, arrayIdentifier), lua.createNumericLiteral(1), lua.SyntaxKind.AdditionOperator);
48
+ const expressionIsUsed = (0, typescript_1.expressionResultIsUsed)(node);
49
49
  if (expressionIsUsed) {
50
50
  // store length in a temp
51
51
  lengthExpression = (0, expression_list_1.moveToPrecedingTemp)(context, lengthExpression);
@@ -91,3 +91,9 @@ export declare const unsupportedOptionalCompileMembersOnly: ((node: ts.Node, ...
91
91
  export declare const undefinedInArrayLiteral: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
92
92
  code: number;
93
93
  };
94
+ export declare const invalidMethodCallExtensionUse: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
95
+ code: number;
96
+ };
97
+ export declare const invalidSpreadInCallExtension: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
98
+ code: number;
99
+ };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.undefinedInArrayLiteral = exports.unsupportedOptionalCompileMembersOnly = exports.unsupportedBuiltinOptionalCall = exports.awaitMustBeInAsyncFunction = exports.notAllowedOptionalAssignment = exports.truthyOnlyConditionalValue = exports.annotationDeprecated = exports.invalidCallExtensionUse = exports.invalidMultiReturnAccess = exports.invalidMultiFunctionReturnType = exports.invalidMultiFunctionUse = exports.unsupportedVarDeclaration = exports.invalidAmbientIdentifierName = exports.unsupportedProperty = exports.unsupportedForTargetButOverrideAvailable = exports.unsupportedForTarget = exports.unsupportedRightShiftOperator = exports.unsupportedAccessorInObjectLiteral = exports.invalidPairsIterableWithoutDestructuring = exports.invalidMultiIterableWithoutDestructuring = exports.invalidRangeControlVariable = exports.invalidVarargUse = exports.invalidRangeUse = exports.annotationInvalidArgumentCount = exports.decoratorInvalidContext = exports.unsupportedOverloadAssignment = exports.unsupportedSelfFunctionConversion = exports.unsupportedNoSelfFunctionConversion = exports.forbiddenForIn = exports.unsupportedNodeKind = void 0;
3
+ exports.invalidSpreadInCallExtension = exports.invalidMethodCallExtensionUse = exports.undefinedInArrayLiteral = exports.unsupportedOptionalCompileMembersOnly = exports.unsupportedBuiltinOptionalCall = exports.awaitMustBeInAsyncFunction = exports.notAllowedOptionalAssignment = exports.truthyOnlyConditionalValue = exports.annotationDeprecated = exports.invalidCallExtensionUse = exports.invalidMultiReturnAccess = exports.invalidMultiFunctionReturnType = exports.invalidMultiFunctionUse = exports.unsupportedVarDeclaration = exports.invalidAmbientIdentifierName = exports.unsupportedProperty = exports.unsupportedForTargetButOverrideAvailable = exports.unsupportedForTarget = exports.unsupportedRightShiftOperator = exports.unsupportedAccessorInObjectLiteral = exports.invalidPairsIterableWithoutDestructuring = exports.invalidMultiIterableWithoutDestructuring = exports.invalidRangeControlVariable = exports.invalidVarargUse = exports.invalidRangeUse = exports.annotationInvalidArgumentCount = exports.decoratorInvalidContext = exports.unsupportedOverloadAssignment = exports.unsupportedSelfFunctionConversion = exports.unsupportedNoSelfFunctionConversion = exports.forbiddenForIn = exports.unsupportedNodeKind = void 0;
4
4
  const ts = require("typescript");
5
5
  const CompilerOptions_1 = require("../../CompilerOptions");
6
6
  const utils_1 = require("../../utils");
@@ -59,4 +59,6 @@ exports.awaitMustBeInAsyncFunction = createErrorDiagnosticFactory("Await can onl
59
59
  exports.unsupportedBuiltinOptionalCall = createErrorDiagnosticFactory("Optional calls are not supported for builtin or language extension functions.");
60
60
  exports.unsupportedOptionalCompileMembersOnly = createErrorDiagnosticFactory("Optional calls are not supported on enums marked with @compileMembersOnly.");
61
61
  exports.undefinedInArrayLiteral = createErrorDiagnosticFactory("Array literals may not contain undefined or null.");
62
+ exports.invalidMethodCallExtensionUse = createErrorDiagnosticFactory("This language extension must be called as a method.");
63
+ exports.invalidSpreadInCallExtension = createErrorDiagnosticFactory("Spread elements are not supported in call extensions.");
62
64
  //# sourceMappingURL=diagnostics.js.map
@@ -63,3 +63,7 @@ export declare enum IterableExtensionKind {
63
63
  export declare function isLuaIterable(context: TransformationContext, type: ts.Type): boolean;
64
64
  export declare function getIterableExtensionTypeForType(context: TransformationContext, type: ts.Type): IterableExtensionKind | undefined;
65
65
  export declare function getIterableExtensionKindForNode(context: TransformationContext, node: ts.Node): IterableExtensionKind | undefined;
66
+ export declare const methodExtensionKinds: ReadonlySet<ExtensionKind>;
67
+ export declare function getNaryCallExtensionArgs(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind, numArgs: number): readonly ts.Expression[] | undefined;
68
+ export declare function getUnaryCallExtensionArg(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind): ts.Expression | undefined;
69
+ export declare function getBinaryCallExtensionArgs(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind): readonly [ts.Expression, ts.Expression] | undefined;
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getIterableExtensionKindForNode = exports.getIterableExtensionTypeForType = exports.isLuaIterable = exports.IterableExtensionKind = exports.getExtensionKindForSymbol = exports.getExtensionKindForNode = exports.getExtensionKindForType = exports.ExtensionKind = void 0;
3
+ exports.getBinaryCallExtensionArgs = exports.getUnaryCallExtensionArg = exports.getNaryCallExtensionArgs = exports.methodExtensionKinds = exports.getIterableExtensionKindForNode = exports.getIterableExtensionTypeForType = exports.isLuaIterable = exports.IterableExtensionKind = exports.getExtensionKindForSymbol = exports.getExtensionKindForNode = exports.getExtensionKindForType = exports.ExtensionKind = void 0;
4
4
  const ts = require("typescript");
5
+ const diagnostics_1 = require("./diagnostics");
5
6
  var ExtensionKind;
6
7
  (function (ExtensionKind) {
7
8
  ExtensionKind["MultiFunction"] = "MultiFunction";
@@ -112,4 +113,68 @@ function getIterableExtensionKindForNode(context, node) {
112
113
  return getIterableExtensionTypeForType(context, type);
113
114
  }
114
115
  exports.getIterableExtensionKindForNode = getIterableExtensionKindForNode;
116
+ exports.methodExtensionKinds = new Set([
117
+ ExtensionKind.AdditionOperatorMethodType,
118
+ ExtensionKind.SubtractionOperatorMethodType,
119
+ ExtensionKind.MultiplicationOperatorMethodType,
120
+ ExtensionKind.DivisionOperatorMethodType,
121
+ ExtensionKind.ModuloOperatorMethodType,
122
+ ExtensionKind.PowerOperatorMethodType,
123
+ ExtensionKind.FloorDivisionOperatorMethodType,
124
+ ExtensionKind.BitwiseAndOperatorMethodType,
125
+ ExtensionKind.BitwiseOrOperatorMethodType,
126
+ ExtensionKind.BitwiseExclusiveOrOperatorMethodType,
127
+ ExtensionKind.BitwiseLeftShiftOperatorMethodType,
128
+ ExtensionKind.BitwiseRightShiftOperatorMethodType,
129
+ ExtensionKind.ConcatOperatorMethodType,
130
+ ExtensionKind.LessThanOperatorMethodType,
131
+ ExtensionKind.GreaterThanOperatorMethodType,
132
+ ExtensionKind.NegationOperatorMethodType,
133
+ ExtensionKind.BitwiseNotOperatorMethodType,
134
+ ExtensionKind.LengthOperatorMethodType,
135
+ ExtensionKind.TableDeleteMethodType,
136
+ ExtensionKind.TableGetMethodType,
137
+ ExtensionKind.TableHasMethodType,
138
+ ExtensionKind.TableSetMethodType,
139
+ ExtensionKind.TableAddKeyMethodType,
140
+ ]);
141
+ function getNaryCallExtensionArgs(context, node, kind, numArgs) {
142
+ let expressions;
143
+ if (node.arguments.some(ts.isSpreadElement)) {
144
+ context.diagnostics.push((0, diagnostics_1.invalidSpreadInCallExtension)(node));
145
+ return undefined;
146
+ }
147
+ if (exports.methodExtensionKinds.has(kind)) {
148
+ if (!(ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression))) {
149
+ context.diagnostics.push((0, diagnostics_1.invalidMethodCallExtensionUse)(node));
150
+ return undefined;
151
+ }
152
+ if (node.arguments.length < numArgs - 1) {
153
+ // assumed to be TS error
154
+ return undefined;
155
+ }
156
+ expressions = [node.expression.expression, ...node.arguments];
157
+ }
158
+ else {
159
+ if (node.arguments.length < numArgs) {
160
+ // assumed to be TS error
161
+ return undefined;
162
+ }
163
+ expressions = node.arguments;
164
+ }
165
+ return expressions;
166
+ }
167
+ exports.getNaryCallExtensionArgs = getNaryCallExtensionArgs;
168
+ function getUnaryCallExtensionArg(context, node, kind) {
169
+ var _a;
170
+ return (_a = getNaryCallExtensionArgs(context, node, kind, 1)) === null || _a === void 0 ? void 0 : _a[0];
171
+ }
172
+ exports.getUnaryCallExtensionArg = getUnaryCallExtensionArg;
173
+ function getBinaryCallExtensionArgs(context, node, kind) {
174
+ const expressions = getNaryCallExtensionArgs(context, node, kind, 2);
175
+ if (expressions === undefined)
176
+ return undefined;
177
+ return [expressions[0], expressions[1]];
178
+ }
179
+ exports.getBinaryCallExtensionArgs = getBinaryCallExtensionArgs;
115
180
  //# sourceMappingURL=language-extensions.js.map
@@ -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
@@ -8,6 +8,7 @@ export declare function hasExportEquals(sourceFile: ts.SourceFile): boolean;
8
8
  */
9
9
  export declare function findFirstNodeAbove<T extends ts.Node>(node: ts.Node, callback: (n: ts.Node) => n is T): T | undefined;
10
10
  export declare function findFirstNonOuterParent(node: ts.Node): ts.Node;
11
+ export declare function expressionResultIsUsed(node: ts.Expression): boolean;
11
12
  export declare function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined;
12
13
  export declare function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean;
13
14
  export declare function isStandardLibraryType(context: TransformationContext, type: ts.Type, name: string | undefined): boolean;