typescript-to-lua 1.3.2 → 1.4.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 (135) hide show
  1. package/dist/CompilerOptions.d.ts +1 -1
  2. package/dist/CompilerOptions.js +0 -1
  3. package/dist/LuaLib.d.ts +12 -1
  4. package/dist/LuaLib.js +61 -65
  5. package/dist/LuaPrinter.js +9 -8
  6. package/dist/cli/parse.js +5 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +5 -1
  9. package/dist/lualib/ArrayConcat.lua +1 -1
  10. package/dist/lualib/ArrayEntries.lua +1 -1
  11. package/dist/lualib/ArrayEvery.lua +2 -2
  12. package/dist/lualib/ArrayFilter.lua +2 -2
  13. package/dist/lualib/ArrayFind.lua +2 -2
  14. package/dist/lualib/ArrayFindIndex.lua +2 -2
  15. package/dist/lualib/ArrayFlat.lua +1 -1
  16. package/dist/lualib/ArrayFlatMap.lua +2 -2
  17. package/dist/lualib/ArrayForEach.lua +2 -2
  18. package/dist/lualib/ArrayIncludes.lua +1 -1
  19. package/dist/lualib/ArrayIndexOf.lua +1 -1
  20. package/dist/lualib/ArrayIsArray.lua +1 -1
  21. package/dist/lualib/ArrayJoin.lua +1 -1
  22. package/dist/lualib/ArrayMap.lua +2 -2
  23. package/dist/lualib/ArrayPush.lua +1 -1
  24. package/dist/lualib/ArrayReduce.lua +2 -2
  25. package/dist/lualib/ArrayReduceRight.lua +2 -2
  26. package/dist/lualib/ArrayReverse.lua +1 -1
  27. package/dist/lualib/ArraySetLength.lua +1 -1
  28. package/dist/lualib/ArrayShift.lua +1 -1
  29. package/dist/lualib/ArraySlice.lua +1 -1
  30. package/dist/lualib/ArraySome.lua +2 -2
  31. package/dist/lualib/ArraySort.lua +2 -2
  32. package/dist/lualib/ArraySplice.lua +1 -1
  33. package/dist/lualib/ArrayToObject.lua +1 -1
  34. package/dist/lualib/ArrayUnshift.lua +1 -1
  35. package/dist/lualib/Await.lua +13 -13
  36. package/dist/lualib/Class.lua +1 -1
  37. package/dist/lualib/ClassExtends.lua +1 -1
  38. package/dist/lualib/CloneDescriptor.lua +1 -1
  39. package/dist/lualib/Decorate.lua +5 -5
  40. package/dist/lualib/DecorateParam.lua +2 -2
  41. package/dist/lualib/DelegatedYield.lua +1 -1
  42. package/dist/lualib/Delete.lua +1 -1
  43. package/dist/lualib/Error.lua +68 -69
  44. package/dist/lualib/FunctionBind.lua +1 -1
  45. package/dist/lualib/Generator.lua +26 -23
  46. package/dist/lualib/InstanceOf.lua +1 -1
  47. package/dist/lualib/InstanceOfObject.lua +1 -1
  48. package/dist/lualib/Iterator.lua +35 -32
  49. package/dist/lualib/Map.lua +131 -129
  50. package/dist/lualib/MathAtan2.lua +1 -1
  51. package/dist/lualib/MathSign.lua +1 -1
  52. package/dist/lualib/New.lua +1 -1
  53. package/dist/lualib/Number.lua +1 -1
  54. package/dist/lualib/NumberIsFinite.lua +1 -1
  55. package/dist/lualib/NumberIsNaN.lua +1 -1
  56. package/dist/lualib/NumberToString.lua +42 -39
  57. package/dist/lualib/ObjectAssign.lua +1 -1
  58. package/dist/lualib/ObjectDefineProperty.lua +1 -1
  59. package/dist/lualib/ObjectEntries.lua +1 -1
  60. package/dist/lualib/ObjectFromEntries.lua +1 -1
  61. package/dist/lualib/ObjectGetOwnPropertyDescriptor.lua +1 -1
  62. package/dist/lualib/ObjectGetOwnPropertyDescriptors.lua +1 -1
  63. package/dist/lualib/ObjectKeys.lua +1 -1
  64. package/dist/lualib/ObjectRest.lua +1 -1
  65. package/dist/lualib/ObjectValues.lua +1 -1
  66. package/dist/lualib/ParseFloat.lua +1 -1
  67. package/dist/lualib/ParseInt.lua +39 -36
  68. package/dist/lualib/Promise.lua +148 -152
  69. package/dist/lualib/PromiseAll.lua +5 -5
  70. package/dist/lualib/PromiseAllSettled.lua +5 -5
  71. package/dist/lualib/PromiseAny.lua +5 -5
  72. package/dist/lualib/PromiseRace.lua +5 -5
  73. package/dist/lualib/Set.lua +120 -118
  74. package/dist/lualib/SetDescriptor.lua +67 -64
  75. package/dist/lualib/SourceMapTraceBack.lua +7 -6
  76. package/dist/lualib/SparseArrayNew.lua +1 -1
  77. package/dist/lualib/SparseArrayPush.lua +1 -1
  78. package/dist/lualib/SparseArraySpread.lua +1 -1
  79. package/dist/lualib/Spread.lua +1 -1
  80. package/dist/lualib/StringAccess.lua +1 -1
  81. package/dist/lualib/StringCharAt.lua +1 -1
  82. package/dist/lualib/StringCharCodeAt.lua +1 -1
  83. package/dist/lualib/StringConcat.lua +1 -1
  84. package/dist/lualib/StringEndsWith.lua +1 -1
  85. package/dist/lualib/StringIncludes.lua +1 -1
  86. package/dist/lualib/StringPadEnd.lua +1 -1
  87. package/dist/lualib/StringPadStart.lua +1 -1
  88. package/dist/lualib/StringReplace.lua +2 -2
  89. package/dist/lualib/StringReplaceAll.lua +4 -4
  90. package/dist/lualib/StringSlice.lua +1 -1
  91. package/dist/lualib/StringSplit.lua +1 -1
  92. package/dist/lualib/StringStartsWith.lua +1 -1
  93. package/dist/lualib/StringSubstr.lua +1 -1
  94. package/dist/lualib/StringSubstring.lua +1 -1
  95. package/dist/lualib/StringTrim.lua +1 -1
  96. package/dist/lualib/StringTrimEnd.lua +1 -1
  97. package/dist/lualib/StringTrimStart.lua +1 -1
  98. package/dist/lualib/Symbol.lua +14 -11
  99. package/dist/lualib/SymbolRegistry.lua +13 -10
  100. package/dist/lualib/TypeOf.lua +1 -1
  101. package/dist/lualib/Unpack.lua +1 -1
  102. package/dist/lualib/WeakMap.lua +41 -39
  103. package/dist/lualib/WeakSet.lua +37 -35
  104. package/dist/lualib/lualib_bundle.lua +1054 -924
  105. package/dist/lualib/lualib_module_info.json +619 -0
  106. package/dist/lualib-build/plugin.d.ts +23 -0
  107. package/dist/lualib-build/plugin.js +138 -0
  108. package/dist/lualib-build/util.d.ts +19 -0
  109. package/dist/lualib-build/util.js +43 -0
  110. package/dist/transformation/builtins/function.js +2 -1
  111. package/dist/transformation/builtins/index.d.ts +1 -0
  112. package/dist/transformation/builtins/index.js +63 -16
  113. package/dist/transformation/context/index.js +5 -1
  114. package/dist/transformation/utils/diagnostics.d.ts +3 -0
  115. package/dist/transformation/utils/diagnostics.js +2 -1
  116. package/dist/transformation/utils/typescript/index.js +5 -1
  117. package/dist/transformation/utils/typescript/types.d.ts +2 -0
  118. package/dist/transformation/utils/typescript/types.js +10 -1
  119. package/dist/transformation/visitors/class/index.js +1 -5
  120. package/dist/transformation/visitors/class/members/constructor.js +1 -3
  121. package/dist/transformation/visitors/class/members/fields.js +12 -8
  122. package/dist/transformation/visitors/class/new.d.ts +1 -2
  123. package/dist/transformation/visitors/class/new.js +1 -40
  124. package/dist/transformation/visitors/conditional.js +15 -14
  125. package/dist/transformation/visitors/identifier.js +5 -0
  126. package/dist/transformation/visitors/literal.js +22 -0
  127. package/dist/transformation/visitors/modules/import.js +4 -14
  128. package/dist/transpilation/bundle.js +1 -1
  129. package/dist/transpilation/index.js +5 -1
  130. package/dist/transpilation/plugins.d.ts +11 -0
  131. package/dist/transpilation/resolve.js +2 -2
  132. package/dist/transpilation/transpile.js +13 -0
  133. package/dist/transpilation/transpiler.js +6 -2
  134. package/package.json +12 -11
  135. package/CHANGELOG.md +0 -703
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lualibDiagnostic = void 0;
4
+ const ts = require("typescript");
5
+ const tstl = require("..");
6
+ const path = require("path");
7
+ const lualib_1 = require("../transformation/utils/lualib");
8
+ const LuaLib_1 = require("../LuaLib");
9
+ const util_1 = require("./util");
10
+ const utils_1 = require("../utils");
11
+ exports.lualibDiagnostic = (0, utils_1.createDiagnosticFactoryWithCode)(200000, (message, file) => ({
12
+ messageText: message,
13
+ file,
14
+ start: file && 0,
15
+ length: file && 0,
16
+ }));
17
+ class LuaLibPlugin {
18
+ constructor() {
19
+ // Plugin members
20
+ this.visitors = {
21
+ [ts.SyntaxKind.SourceFile]: this.lualibFileVisitor.bind(this),
22
+ };
23
+ this.printer = (program, emitHost, fileName, file) => new LuaLibPrinter(emitHost, program, fileName).print(file);
24
+ // Internals
25
+ this.featureExports = new Map();
26
+ this.featureDependencies = new Map();
27
+ }
28
+ afterPrint(program, options, emitHost, result) {
29
+ var _a;
30
+ void options;
31
+ // Write lualib dependency json
32
+ const { result: luaLibModuleInfo, diagnostics } = this.createLuaLibModulesInfo();
33
+ const emitBOM = (_a = options.emitBOM) !== null && _a !== void 0 ? _a : false;
34
+ emitHost.writeFile(path.join(tstl.getEmitOutDir(program), LuaLib_1.luaLibModulesInfoFileName), JSON.stringify(luaLibModuleInfo, null, 2), emitBOM);
35
+ // Create map of result files keyed by their 'lualib name'
36
+ const exportedLualibFeatures = new Map(result.map(f => [path.basename(f.fileName).split(".")[0], f.code]));
37
+ // Figure out the order required in the bundle by recursively resolving all dependency features
38
+ const allFeatures = Object.values(LuaLib_1.LuaLibFeature);
39
+ const orderedFeatures = (0, LuaLib_1.resolveRecursiveLualibFeatures)(allFeatures, emitHost, luaLibModuleInfo);
40
+ // Concatenate lualib files into bundle with exports table and add lualib_bundle.lua to results
41
+ let lualibBundle = orderedFeatures.map(f => exportedLualibFeatures.get(LuaLib_1.LuaLibFeature[f])).join("\n");
42
+ const exports = allFeatures.flatMap(feature => luaLibModuleInfo[feature].exports);
43
+ lualibBundle += `\nreturn {\n${exports.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`;
44
+ result.push({ fileName: "lualib_bundle.lua", code: lualibBundle });
45
+ return diagnostics;
46
+ }
47
+ lualibFileVisitor(file, context) {
48
+ const featureName = path.basename(file.fileName, ".ts");
49
+ if (!(featureName in tstl.LuaLibFeature)) {
50
+ context.diagnostics.push((0, exports.lualibDiagnostic)(`File is not a lualib feature: ${featureName}`, file));
51
+ }
52
+ // Transpile file as normal with tstl
53
+ const fileResult = context.superTransformNode(file)[0];
54
+ const usedFeatures = new Set((0, lualib_1.getUsedLuaLibFeatures)(context));
55
+ // Get all imports in file
56
+ const importNames = new Set();
57
+ const imports = file.statements.filter(ts.isImportDeclaration);
58
+ for (const { importClause, moduleSpecifier } of imports) {
59
+ if ((importClause === null || importClause === void 0 ? void 0 : importClause.namedBindings) && ts.isNamedImports(importClause.namedBindings)) {
60
+ for (const { name } of importClause.namedBindings.elements) {
61
+ importNames.add(name.text);
62
+ }
63
+ }
64
+ // track lualib imports
65
+ if (ts.isStringLiteral(moduleSpecifier)) {
66
+ const featureName = path.basename(moduleSpecifier.text, ".ts");
67
+ if (featureName in tstl.LuaLibFeature) {
68
+ usedFeatures.add(featureName);
69
+ }
70
+ }
71
+ }
72
+ const filteredStatements = fileResult.statements
73
+ .filter(s => !(0, util_1.isExportTableDeclaration)(s) && !(0, util_1.isRequire)(s) && !(0, util_1.isImport)(s, importNames) && !(0, util_1.isExportsReturn)(s))
74
+ .map(statement => {
75
+ if ((0, util_1.isExportAlias)(statement)) {
76
+ const name = statement.left[0];
77
+ const exportName = statement.right[0].index.value;
78
+ if (name.text === exportName)
79
+ return undefined; // Remove "x = x" statements
80
+ return tstl.createAssignmentStatement(name, tstl.createIdentifier(exportName));
81
+ }
82
+ return statement;
83
+ })
84
+ .filter(statement => statement !== undefined);
85
+ const exportNames = filteredStatements.filter(util_1.isExportAssignment).map(s => s.left[0].index.value);
86
+ if (!filteredStatements.every(util_1.isExportAssignment)) {
87
+ // If there are local statements, wrap them in a do ... end with exports outside
88
+ const exports = tstl.createVariableDeclarationStatement(exportNames.map(k => tstl.createIdentifier(k)));
89
+ // transform export assignments to local assignments
90
+ const bodyStatements = filteredStatements.map(s => (0, util_1.isExportAssignment)(s)
91
+ ? tstl.createAssignmentStatement(tstl.createIdentifier(s.left[0].index.value), s.right[0])
92
+ : s);
93
+ fileResult.statements = [exports, tstl.createDoStatement(bodyStatements)];
94
+ }
95
+ else {
96
+ // transform export assignments to local variable declarations
97
+ fileResult.statements = filteredStatements.map(s => tstl.createVariableDeclarationStatement(tstl.createIdentifier(s.left[0].index.value), s.right[0]));
98
+ }
99
+ // Save dependency information
100
+ this.featureExports.set(featureName, new Set(exportNames));
101
+ if (usedFeatures.size > 0) {
102
+ this.featureDependencies.set(featureName, usedFeatures);
103
+ }
104
+ return fileResult;
105
+ }
106
+ createLuaLibModulesInfo() {
107
+ const result = {};
108
+ const diagnostics = [];
109
+ for (const feature of Object.values(tstl.LuaLibFeature)) {
110
+ const exports = this.featureExports.get(feature);
111
+ if (!exports) {
112
+ diagnostics.push((0, exports.lualibDiagnostic)(`Missing file for lualib feature: ${feature}`));
113
+ continue;
114
+ }
115
+ const dependencies = this.featureDependencies.get(feature);
116
+ result[feature] = {
117
+ exports: Array.from(exports),
118
+ dependencies: dependencies ? Array.from(dependencies) : undefined,
119
+ };
120
+ }
121
+ return { result: result, diagnostics };
122
+ }
123
+ }
124
+ class LuaLibPrinter extends tstl.LuaPrinter {
125
+ // Strip all exports during print
126
+ printTableIndexExpression(expression) {
127
+ if (tstl.isIdentifier(expression.table) &&
128
+ expression.table.text === "____exports" &&
129
+ tstl.isStringLiteral(expression.index)) {
130
+ return super.printExpression(tstl.createIdentifier(expression.index.value));
131
+ }
132
+ return super.printTableIndexExpression(expression);
133
+ }
134
+ }
135
+ const pluginInstance = new LuaLibPlugin();
136
+ // eslint-disable-next-line import/no-default-export
137
+ exports.default = pluginInstance;
138
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1,19 @@
1
+ import * as tstl from "..";
2
+ export declare function isExportTableDeclaration(node: tstl.Node): node is tstl.VariableDeclarationStatement & {
3
+ left: [];
4
+ };
5
+ export declare function isExportTable(node: tstl.Node): node is tstl.Identifier;
6
+ export declare type ExportTableIndex = tstl.TableIndexExpression & {
7
+ index: tstl.StringLiteral;
8
+ };
9
+ export declare function isExportTableIndex(node: tstl.Node): node is ExportTableIndex;
10
+ export declare function isExportAlias(node: tstl.Node): node is tstl.VariableDeclarationStatement & {
11
+ right: [ExportTableIndex];
12
+ };
13
+ export declare type ExportAssignment = tstl.AssignmentStatement & {
14
+ left: [ExportTableIndex];
15
+ };
16
+ export declare function isExportAssignment(node: tstl.Node): node is ExportAssignment;
17
+ export declare function isRequire(node: tstl.Node): boolean | undefined;
18
+ export declare function isImport(node: tstl.Node, importNames: Set<string>): boolean;
19
+ export declare function isExportsReturn(node: tstl.Node): boolean;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isExportsReturn = exports.isImport = exports.isRequire = exports.isExportAssignment = exports.isExportAlias = exports.isExportTableIndex = exports.isExportTable = exports.isExportTableDeclaration = void 0;
4
+ const tstl = require("..");
5
+ function isExportTableDeclaration(node) {
6
+ return tstl.isVariableDeclarationStatement(node) && isExportTable(node.left[0]);
7
+ }
8
+ exports.isExportTableDeclaration = isExportTableDeclaration;
9
+ function isExportTable(node) {
10
+ return tstl.isIdentifier(node) && node.text === "____exports";
11
+ }
12
+ exports.isExportTable = isExportTable;
13
+ function isExportTableIndex(node) {
14
+ return tstl.isTableIndexExpression(node) && isExportTable(node.table) && tstl.isStringLiteral(node.index);
15
+ }
16
+ exports.isExportTableIndex = isExportTableIndex;
17
+ function isExportAlias(node) {
18
+ return tstl.isVariableDeclarationStatement(node) && node.right !== undefined && isExportTableIndex(node.right[0]);
19
+ }
20
+ exports.isExportAlias = isExportAlias;
21
+ function isExportAssignment(node) {
22
+ return tstl.isAssignmentStatement(node) && isExportTableIndex(node.left[0]);
23
+ }
24
+ exports.isExportAssignment = isExportAssignment;
25
+ function isRequire(node) {
26
+ return (tstl.isVariableDeclarationStatement(node) &&
27
+ node.right &&
28
+ tstl.isCallExpression(node.right[0]) &&
29
+ tstl.isIdentifier(node.right[0].expression) &&
30
+ node.right[0].expression.text === "require");
31
+ }
32
+ exports.isRequire = isRequire;
33
+ function isImport(node, importNames) {
34
+ return tstl.isVariableDeclarationStatement(node) && importNames.has(node.left[0].text);
35
+ }
36
+ exports.isImport = isImport;
37
+ function isExportsReturn(node) {
38
+ return (tstl.isReturnStatement(node) &&
39
+ tstl.isIdentifier(node.expressions[0]) &&
40
+ node.expressions[0].text === "____exports");
41
+ }
42
+ exports.isExportsReturn = isExportsReturn;
43
+ //# sourceMappingURL=util.js.map
@@ -19,7 +19,8 @@ function transformFunctionPrototypeCall(context, node) {
19
19
  const expressionName = expression.name.text;
20
20
  switch (expressionName) {
21
21
  case "apply":
22
- return lua.createCallExpression(caller, [params[0], (0, lua_ast_1.createUnpackCall)(context, params[1], node.arguments[1])], node);
22
+ const nonContextArgs = params.length > 1 ? [(0, lua_ast_1.createUnpackCall)(context, params[1], node.arguments[1])] : [];
23
+ return lua.createCallExpression(caller, [params[0], ...nonContextArgs], node);
23
24
  case "bind":
24
25
  return (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.FunctionBind, node, caller, ...params);
25
26
  case "call":
@@ -4,3 +4,4 @@ import { TransformationContext } from "../context";
4
4
  export declare function transformBuiltinPropertyAccessExpression(context: TransformationContext, node: ts.PropertyAccessExpression): lua.Expression | undefined;
5
5
  export declare function transformBuiltinCallExpression(context: TransformationContext, node: ts.CallExpression, isOptionalCall: boolean): lua.Expression | undefined;
6
6
  export declare function transformBuiltinIdentifierExpression(context: TransformationContext, node: ts.Identifier): lua.Expression | undefined;
7
+ export declare function checkForLuaLibType(context: TransformationContext, type: ts.Type): void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformBuiltinIdentifierExpression = exports.transformBuiltinCallExpression = exports.transformBuiltinPropertyAccessExpression = void 0;
3
+ exports.checkForLuaLibType = exports.transformBuiltinIdentifierExpression = exports.transformBuiltinCallExpression = exports.transformBuiltinPropertyAccessExpression = void 0;
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../LuaAST");
6
6
  const utils_1 = require("../../utils");
@@ -8,7 +8,6 @@ const lua_ast_1 = require("../utils/lua-ast");
8
8
  const lualib_1 = require("../utils/lualib");
9
9
  const symbols_1 = require("../utils/symbols");
10
10
  const typescript_1 = require("../utils/typescript");
11
- const new_1 = require("../visitors/class/new");
12
11
  const array_1 = require("./array");
13
12
  const console_1 = require("./console");
14
13
  const function_1 = require("./function");
@@ -22,6 +21,14 @@ const symbol_1 = require("./symbol");
22
21
  const diagnostics_1 = require("../utils/diagnostics");
23
22
  function transformBuiltinPropertyAccessExpression(context, node) {
24
23
  const ownerType = context.checker.getTypeAtLocation(node.expression);
24
+ if (ts.isIdentifier(node.expression) && (0, typescript_1.isStandardLibraryType)(context, ownerType, undefined)) {
25
+ switch (node.expression.text) {
26
+ case "Math":
27
+ return (0, math_1.transformMathProperty)(context, node);
28
+ case "Symbol":
29
+ (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Symbol);
30
+ }
31
+ }
25
32
  if ((0, typescript_1.isStringType)(context, ownerType)) {
26
33
  return (0, string_1.transformStringProperty)(context, node);
27
34
  }
@@ -31,14 +38,6 @@ function transformBuiltinPropertyAccessExpression(context, node) {
31
38
  if ((0, typescript_1.isFunctionType)(ownerType)) {
32
39
  return (0, function_1.transformFunctionProperty)(context, node);
33
40
  }
34
- if (ts.isIdentifier(node.expression) && (0, typescript_1.isStandardLibraryType)(context, ownerType, undefined)) {
35
- switch (node.expression.text) {
36
- case "Math":
37
- return (0, math_1.transformMathProperty)(context, node);
38
- case "Symbol":
39
- (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Symbol);
40
- }
41
- }
42
41
  }
43
42
  exports.transformBuiltinPropertyAccessExpression = transformBuiltinPropertyAccessExpression;
44
43
  function transformBuiltinCallExpression(context, node, isOptionalCall) {
@@ -48,8 +47,7 @@ function transformBuiltinCallExpression(context, node, isOptionalCall) {
48
47
  };
49
48
  const expressionType = context.checker.getTypeAtLocation(node.expression);
50
49
  if (ts.isIdentifier(node.expression) && (0, typescript_1.isStandardLibraryType)(context, expressionType, undefined)) {
51
- // TODO:
52
- (0, new_1.checkForLuaLibType)(context, expressionType);
50
+ checkForLuaLibType(context, expressionType);
53
51
  const result = (0, global_1.transformGlobalCall)(context, node);
54
52
  if (result) {
55
53
  if (isOptionalCall)
@@ -102,22 +100,30 @@ function transformBuiltinCallExpression(context, node, isOptionalCall) {
102
100
  return (0, promise_1.transformPromiseConstructorCall)(context, node);
103
101
  }
104
102
  }
105
- if ((0, typescript_1.isStringType)(context, ownerType) && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
103
+ const isStringFunction = (0, typescript_1.isStringType)(context, ownerType) ||
104
+ (expression.questionDotToken && (0, typescript_1.isNullableType)(context, ownerType, typescript_1.isStringType));
105
+ if (isStringFunction && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
106
106
  if (isOptionalCall)
107
107
  return unsupportedOptionalCall();
108
108
  return (0, string_1.transformStringPrototypeCall)(context, node);
109
109
  }
110
- if ((0, typescript_1.isNumberType)(context, ownerType) && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
110
+ const isNumberFunction = (0, typescript_1.isNumberType)(context, ownerType) ||
111
+ (expression.questionDotToken && (0, typescript_1.isNullableType)(context, ownerType, typescript_1.isNumberType));
112
+ if (isNumberFunction && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
111
113
  if (isOptionalCall)
112
114
  return unsupportedOptionalCall();
113
115
  return (0, number_1.transformNumberPrototypeCall)(context, node);
114
116
  }
115
- if ((0, typescript_1.isArrayType)(context, ownerType) && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
117
+ const isArrayFunction = (0, typescript_1.isArrayType)(context, ownerType) ||
118
+ (expression.questionDotToken && (0, typescript_1.isNullableType)(context, ownerType, typescript_1.isArrayType));
119
+ if (isArrayFunction && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
116
120
  if (isOptionalCall)
117
121
  return unsupportedOptionalCall();
118
122
  return (0, array_1.transformArrayPrototypeCall)(context, node);
119
123
  }
120
- if ((0, typescript_1.isFunctionType)(ownerType) && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
124
+ const isFunctionFunction = (0, typescript_1.isFunctionType)(ownerType) ||
125
+ (expression.questionDotToken && (0, typescript_1.isNullableType)(context, ownerType, (_, t) => (0, typescript_1.isFunctionType)(t)));
126
+ if (isFunctionFunction && (0, typescript_1.hasStandardLibrarySignature)(context, node)) {
121
127
  if (isOptionalCall)
122
128
  return unsupportedOptionalCall();
123
129
  return (0, function_1.transformFunctionPrototypeCall)(context, node);
@@ -143,4 +149,45 @@ function transformBuiltinIdentifierExpression(context, node) {
143
149
  }
144
150
  }
145
151
  exports.transformBuiltinIdentifierExpression = transformBuiltinIdentifierExpression;
152
+ const builtinErrorTypeNames = new Set([
153
+ "Error",
154
+ "ErrorConstructor",
155
+ "RangeError",
156
+ "RangeErrorConstructor",
157
+ "ReferenceError",
158
+ "ReferenceErrorConstructor",
159
+ "SyntaxError",
160
+ "SyntaxErrorConstructor",
161
+ "TypeError",
162
+ "TypeErrorConstructor",
163
+ "URIError",
164
+ "URIErrorConstructor",
165
+ ]);
166
+ function checkForLuaLibType(context, type) {
167
+ if (!type.symbol)
168
+ return;
169
+ const name = context.checker.getFullyQualifiedName(type.symbol);
170
+ switch (name) {
171
+ case "Map":
172
+ case "MapConstructor":
173
+ (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Map);
174
+ return;
175
+ case "Set":
176
+ case "SetConstructor":
177
+ (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Set);
178
+ return;
179
+ case "WeakMap":
180
+ case "WeakMapConstructor":
181
+ (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.WeakMap);
182
+ return;
183
+ case "WeakSet":
184
+ case "WeakSetConstructor":
185
+ (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.WeakSet);
186
+ return;
187
+ }
188
+ if (builtinErrorTypeNames.has(name)) {
189
+ (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Error);
190
+ }
191
+ }
192
+ exports.checkForLuaLibType = checkForLuaLibType;
146
193
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -94,3 +94,6 @@ export declare const unsupportedBuiltinOptionalCall: ((node: ts.Node, ...args: a
94
94
  export declare const unsupportedOptionalCompileMembersOnly: ((node: ts.Node, ...args: any[]) => ts.Diagnostic) & {
95
95
  code: number;
96
96
  };
97
+ export declare const undefinedInArrayLiteral: ((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.unsupportedOptionalCompileMembersOnly = exports.unsupportedBuiltinOptionalCall = exports.awaitMustBeInAsyncFunction = exports.notAllowedOptionalAssignment = exports.annotationDeprecated = exports.annotationRemoved = exports.invalidTableExtensionUse = exports.invalidOperatorMappingUse = exports.invalidMultiReturnAccess = exports.invalidMultiTypeToEmptyPatternOrArrayLiteral = exports.invalidMultiTypeToNonArrayLiteral = exports.invalidMultiFunctionReturnType = exports.invalidMultiFunctionUse = exports.unsupportedVarDeclaration = exports.invalidAmbientIdentifierName = exports.unsupportedProperty = 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.undefinedInArrayLiteral = exports.unsupportedOptionalCompileMembersOnly = exports.unsupportedBuiltinOptionalCall = exports.awaitMustBeInAsyncFunction = exports.notAllowedOptionalAssignment = exports.annotationDeprecated = exports.annotationRemoved = exports.invalidTableExtensionUse = exports.invalidOperatorMappingUse = exports.invalidMultiReturnAccess = exports.invalidMultiTypeToEmptyPatternOrArrayLiteral = exports.invalidMultiTypeToNonArrayLiteral = exports.invalidMultiFunctionReturnType = exports.invalidMultiFunctionUse = exports.unsupportedVarDeclaration = exports.invalidAmbientIdentifierName = exports.unsupportedProperty = 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,5 @@ exports.notAllowedOptionalAssignment = createErrorDiagnosticFactory("The left-ha
59
59
  exports.awaitMustBeInAsyncFunction = createErrorDiagnosticFactory("Await can only be used inside async functions.");
60
60
  exports.unsupportedBuiltinOptionalCall = createErrorDiagnosticFactory("Optional calls are not supported for builtin or language extension functions.");
61
61
  exports.unsupportedOptionalCompileMembersOnly = createErrorDiagnosticFactory("Optional calls are not supported on enums marked with @compileMembersOnly.");
62
+ exports.undefinedInArrayLiteral = createErrorDiagnosticFactory("Array literals may not contain undefined or null.");
62
63
  //# sourceMappingURL=diagnostics.js.map
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
3
  if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
5
9
  }) : (function(o, m, k, k2) {
6
10
  if (k2 === undefined) k2 = k;
7
11
  o[k2] = m[k];
@@ -3,8 +3,10 @@ import { TransformationContext } from "../../context";
3
3
  export declare function isTypeWithFlags(context: TransformationContext, type: ts.Type, flags: ts.TypeFlags): boolean;
4
4
  export declare function typeAlwaysSatisfies(context: TransformationContext, type: ts.Type, predicate: (type: ts.Type) => boolean): boolean;
5
5
  export declare function typeCanSatisfy(context: TransformationContext, type: ts.Type, predicate: (type: ts.Type) => boolean): boolean;
6
+ export declare function isNullishType(context: TransformationContext, type: ts.Type): boolean;
6
7
  export declare function isStringType(context: TransformationContext, type: ts.Type): boolean;
7
8
  export declare function isNumberType(context: TransformationContext, type: ts.Type): boolean;
9
+ export declare function isNullableType(context: TransformationContext, type: ts.Type, isType: (c: TransformationContext, t: ts.Type) => boolean): boolean;
8
10
  /**
9
11
  * Iterate over a type and its bases until the callback returns true.
10
12
  */
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.canBeFalsyWhenNotNull = exports.canBeFalsy = exports.isFunctionType = exports.isArrayType = exports.forTypeOrAnySupertype = exports.isNumberType = exports.isStringType = exports.typeCanSatisfy = exports.typeAlwaysSatisfies = exports.isTypeWithFlags = void 0;
3
+ exports.canBeFalsyWhenNotNull = exports.canBeFalsy = exports.isFunctionType = exports.isArrayType = exports.forTypeOrAnySupertype = exports.isNullableType = exports.isNumberType = exports.isStringType = exports.isNullishType = exports.typeCanSatisfy = exports.typeAlwaysSatisfies = exports.isTypeWithFlags = void 0;
4
4
  const ts = require("typescript");
5
5
  function isTypeWithFlags(context, type, flags) {
6
6
  const predicate = (type) => (type.flags & flags) !== 0;
@@ -46,6 +46,10 @@ function typeCanSatisfy(context, type, predicate) {
46
46
  return false;
47
47
  }
48
48
  exports.typeCanSatisfy = typeCanSatisfy;
49
+ function isNullishType(context, type) {
50
+ return isTypeWithFlags(context, type, ts.TypeFlags.Undefined | ts.TypeFlags.Null | ts.TypeFlags.VoidLike);
51
+ }
52
+ exports.isNullishType = isNullishType;
49
53
  function isStringType(context, type) {
50
54
  return isTypeWithFlags(context, type, ts.TypeFlags.String | ts.TypeFlags.StringLike | ts.TypeFlags.StringLiteral);
51
55
  }
@@ -54,6 +58,11 @@ function isNumberType(context, type) {
54
58
  return isTypeWithFlags(context, type, ts.TypeFlags.Number | ts.TypeFlags.NumberLike | ts.TypeFlags.NumberLiteral);
55
59
  }
56
60
  exports.isNumberType = isNumberType;
61
+ function isNullableType(context, type, isType) {
62
+ return (typeCanSatisfy(context, type, t => isType(context, t)) &&
63
+ typeAlwaysSatisfies(context, type, t => isType(context, t) || isNullishType(context, t)));
64
+ }
65
+ exports.isNullableType = isNullableType;
57
66
  function isExplicitArrayType(context, type) {
58
67
  if (type.symbol) {
59
68
  const baseConstraint = context.checker.getBaseConstraintOfType(type);
@@ -15,9 +15,8 @@ const accessors_1 = require("./members/accessors");
15
15
  const constructor_1 = require("./members/constructor");
16
16
  const fields_1 = require("./members/fields");
17
17
  const method_1 = require("./members/method");
18
- const new_1 = require("./new");
19
- const setup_1 = require("./setup");
20
18
  const utils_2 = require("./utils");
19
+ const setup_1 = require("./setup");
21
20
  const transformClassDeclaration = (declaration, context) => {
22
21
  // If declaration is a default export, transform to export variable assignment instead
23
22
  if ((0, export_1.hasDefaultExportModifier)(declaration)) {
@@ -61,9 +60,6 @@ function transformClassLikeDeclaration(classDeclaration, context, nameOverride)
61
60
  const extendedType = (0, utils_2.getExtendedType)(context, classDeclaration);
62
61
  const superInfo = (0, utils_1.getOrUpdate)(classSuperInfos, context, () => []);
63
62
  superInfo.push({ className, extendedTypeNode });
64
- if (extendedType) {
65
- (0, new_1.checkForLuaLibType)(context, extendedType);
66
- }
67
63
  // Get all properties with value
68
64
  const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer);
69
65
  // Divide properties into static and non-static
@@ -4,7 +4,6 @@ exports.transformConstructorDeclaration = exports.createConstructorName = export
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../../../LuaAST");
6
6
  const lua_ast_1 = require("../../../utils/lua-ast");
7
- const preceding_statements_1 = require("../../../utils/preceding-statements");
8
7
  const scope_1 = require("../../../utils/scope");
9
8
  const function_1 = require("../../function");
10
9
  const identifier_1 = require("../../identifier");
@@ -30,7 +29,7 @@ function transformConstructorDeclaration(context, statement, className, instance
30
29
  const bodyWithFieldInitializers = (0, function_1.transformFunctionBodyHeader)(context, scope, statement.parameters, restParamName);
31
30
  // Check for field declarations in constructor
32
31
  const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined);
33
- const [fieldsPrecedingStatements, classInstanceFields] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => (0, fields_1.transformClassInstanceFields)(context, instanceFields));
32
+ const classInstanceFields = (0, fields_1.transformClassInstanceFields)(context, instanceFields);
34
33
  // If there are field initializers and the first statement is a super call,
35
34
  // move super call between default assignments and initializers
36
35
  if ((constructorFieldsDeclarations.length > 0 || classInstanceFields.length > 0) &&
@@ -55,7 +54,6 @@ function transformConstructorDeclaration(context, statement, className, instance
55
54
  }
56
55
  // else { TypeScript error: A parameter property may not be declared using a binding pattern }
57
56
  }
58
- bodyWithFieldInitializers.push(...fieldsPrecedingStatements);
59
57
  bodyWithFieldInitializers.push(...classInstanceFields);
60
58
  bodyWithFieldInitializers.push(...body);
61
59
  const block = lua.createBlock(bodyWithFieldInitializers);
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transformStaticPropertyDeclaration = exports.transformClassInstanceFields = exports.createPropertyDecoratingExpression = void 0;
4
4
  const lua = require("../../../../LuaAST");
5
5
  const lua_ast_1 = require("../../../utils/lua-ast");
6
+ const preceding_statements_1 = require("../../../utils/preceding-statements");
6
7
  const literal_1 = require("../../literal");
7
8
  const decorators_1 = require("../decorators");
8
9
  const method_1 = require("./method");
@@ -17,14 +18,17 @@ exports.createPropertyDecoratingExpression = createPropertyDecoratingExpression;
17
18
  function transformClassInstanceFields(context, instanceFields) {
18
19
  const statements = [];
19
20
  for (const f of instanceFields) {
20
- // Get identifier
21
- const fieldName = (0, literal_1.transformPropertyName)(context, f.name);
22
- const value = f.initializer ? context.transformExpression(f.initializer) : undefined;
23
- // self[fieldName]
24
- const selfIndex = lua.createTableIndexExpression((0, lua_ast_1.createSelfIdentifier)(), fieldName);
25
- // self[fieldName] = value
26
- const assignClassField = lua.createAssignmentStatement(selfIndex, value, f);
27
- statements.push(assignClassField);
21
+ const [precedingStatements, statement] = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => {
22
+ // Get identifier
23
+ const fieldName = (0, literal_1.transformPropertyName)(context, f.name);
24
+ const value = f.initializer ? context.transformExpression(f.initializer) : undefined;
25
+ // self[fieldName]
26
+ const selfIndex = lua.createTableIndexExpression((0, lua_ast_1.createSelfIdentifier)(), fieldName);
27
+ // self[fieldName] = value
28
+ const assignClassField = lua.createAssignmentStatement(selfIndex, value, f);
29
+ return assignClassField;
30
+ });
31
+ statements.push(...precedingStatements, statement);
28
32
  }
29
33
  return statements;
30
34
  }
@@ -1,4 +1,3 @@
1
1
  import * as ts from "typescript";
2
- import { FunctionVisitor, TransformationContext } from "../../context";
3
- export declare function checkForLuaLibType(context: TransformationContext, type: ts.Type): void;
2
+ import { FunctionVisitor } from "../../context";
4
3
  export declare const transformNewExpression: FunctionVisitor<ts.NewExpression>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformNewExpression = exports.checkForLuaLibType = void 0;
3
+ exports.transformNewExpression = void 0;
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../../LuaAST");
6
6
  const annotations_1 = require("../../utils/annotations");
@@ -8,44 +8,6 @@ const diagnostics_1 = require("../../utils/diagnostics");
8
8
  const lualib_1 = require("../../utils/lualib");
9
9
  const call_1 = require("../call");
10
10
  const table_1 = require("../language-extensions/table");
11
- const builtinErrorTypeNames = new Set([
12
- "Error",
13
- "ErrorConstructor",
14
- "RangeError",
15
- "RangeErrorConstructor",
16
- "ReferenceError",
17
- "ReferenceErrorConstructor",
18
- "SyntaxError",
19
- "SyntaxErrorConstructor",
20
- "TypeError",
21
- "TypeErrorConstructor",
22
- "URIError",
23
- "URIErrorConstructor",
24
- ]);
25
- // TODO: Do it in identifier?
26
- function checkForLuaLibType(context, type) {
27
- if (!type.symbol)
28
- return;
29
- const name = context.checker.getFullyQualifiedName(type.symbol);
30
- switch (name) {
31
- case "Map":
32
- (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Map);
33
- return;
34
- case "Set":
35
- (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Set);
36
- return;
37
- case "WeakMap":
38
- (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.WeakMap);
39
- return;
40
- case "WeakSet":
41
- (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.WeakSet);
42
- return;
43
- }
44
- if (builtinErrorTypeNames.has(name)) {
45
- (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Error);
46
- }
47
- }
48
- exports.checkForLuaLibType = checkForLuaLibType;
49
11
  const transformNewExpression = (node, context) => {
50
12
  var _a, _b;
51
13
  const type = context.checker.getTypeAtLocation(node);
@@ -58,7 +20,6 @@ const transformNewExpression = (node, context) => {
58
20
  }
59
21
  const signature = context.checker.getResolvedSignature(node);
60
22
  const [name, params] = (0, call_1.transformCallAndArguments)(context, node.expression, (_a = node.arguments) !== null && _a !== void 0 ? _a : [ts.factory.createTrue()], signature);
61
- checkForLuaLibType(context, type);
62
23
  const customConstructorAnnotation = annotations.get(annotations_1.AnnotationKind.CustomConstructor);
63
24
  if (customConstructorAnnotation) {
64
25
  if (customConstructorAnnotation.args.length === 1) {