typescript-to-lua 1.20.1 → 1.22.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.
package/dist/LuaLib.d.ts CHANGED
@@ -60,6 +60,7 @@ export declare enum LuaLibFeature {
60
60
  New = "New",
61
61
  Number = "Number",
62
62
  NumberIsFinite = "NumberIsFinite",
63
+ NumberIsInteger = "NumberIsInteger",
63
64
  NumberIsNaN = "NumberIsNaN",
64
65
  NumberParseInt = "ParseInt",
65
66
  NumberParseFloat = "ParseFloat",
package/dist/LuaLib.js CHANGED
@@ -65,6 +65,7 @@ var LuaLibFeature;
65
65
  LuaLibFeature["New"] = "New";
66
66
  LuaLibFeature["Number"] = "Number";
67
67
  LuaLibFeature["NumberIsFinite"] = "NumberIsFinite";
68
+ LuaLibFeature["NumberIsInteger"] = "NumberIsInteger";
68
69
  LuaLibFeature["NumberIsNaN"] = "NumberIsNaN";
69
70
  LuaLibFeature["NumberParseInt"] = "ParseInt";
70
71
  LuaLibFeature["NumberParseFloat"] = "ParseFloat";
@@ -0,0 +1,3 @@
1
+ local function __TS__NumberIsInteger(value)
2
+ return __TS__NumberIsFinite(value) and math.floor(value) == value
3
+ end
@@ -1,6 +1,6 @@
1
1
  local function __TS__Unpack(list, i, j)
2
2
  if i == 1 and j == nil then
3
- return unpack(nil, list)
3
+ return unpack(list)
4
4
  else
5
5
  if j == nil then
6
6
  j = table.getn(list)
@@ -1241,7 +1241,7 @@ end
1241
1241
 
1242
1242
  local function __TS__Unpack(list, i, j)
1243
1243
  if i == 1 and j == nil then
1244
- return unpack(nil, list)
1244
+ return unpack(list)
1245
1245
  else
1246
1246
  if j == nil then
1247
1247
  j = table.getn(list)
@@ -1526,6 +1526,10 @@ local function __TS__NumberIsFinite(value)
1526
1526
  return type(value) == "number" and value == value and value ~= 1 / 0 and value ~= -(1 / 0)
1527
1527
  end
1528
1528
 
1529
+ local function __TS__NumberIsInteger(value)
1530
+ return __TS__NumberIsFinite(value) and math.floor(value) == value
1531
+ end
1532
+
1529
1533
  local function __TS__NumberIsNaN(value)
1530
1534
  return value ~= value
1531
1535
  end
@@ -2627,6 +2631,7 @@ return {
2627
2631
  __TS__New = __TS__New,
2628
2632
  __TS__Number = __TS__Number,
2629
2633
  __TS__NumberIsFinite = __TS__NumberIsFinite,
2634
+ __TS__NumberIsInteger = __TS__NumberIsInteger,
2630
2635
  __TS__NumberIsNaN = __TS__NumberIsNaN,
2631
2636
  __TS__ParseInt = __TS__ParseInt,
2632
2637
  __TS__ParseFloat = __TS__ParseFloat,
@@ -381,6 +381,14 @@
381
381
  "__TS__NumberIsFinite"
382
382
  ]
383
383
  },
384
+ "NumberIsInteger": {
385
+ "exports": [
386
+ "__TS__NumberIsInteger"
387
+ ],
388
+ "dependencies": [
389
+ "NumberIsFinite"
390
+ ]
391
+ },
384
392
  "NumberIsNaN": {
385
393
  "exports": [
386
394
  "__TS__NumberIsNaN"
@@ -0,0 +1,3 @@
1
+ local function __TS__NumberIsInteger(value)
2
+ return __TS__NumberIsFinite(value) and math.floor(value) == value
3
+ end
@@ -1466,6 +1466,10 @@ local function __TS__NumberIsFinite(value)
1466
1466
  return type(value) == "number" and value == value and value ~= math.huge and value ~= -math.huge
1467
1467
  end
1468
1468
 
1469
+ local function __TS__NumberIsInteger(value)
1470
+ return __TS__NumberIsFinite(value) and math.floor(value) == value
1471
+ end
1472
+
1469
1473
  local function __TS__NumberIsNaN(value)
1470
1474
  return value ~= value
1471
1475
  end
@@ -2567,6 +2571,7 @@ return {
2567
2571
  __TS__New = __TS__New,
2568
2572
  __TS__Number = __TS__Number,
2569
2573
  __TS__NumberIsFinite = __TS__NumberIsFinite,
2574
+ __TS__NumberIsInteger = __TS__NumberIsInteger,
2570
2575
  __TS__NumberIsNaN = __TS__NumberIsNaN,
2571
2576
  __TS__ParseInt = __TS__ParseInt,
2572
2577
  __TS__ParseFloat = __TS__ParseFloat,
@@ -387,6 +387,14 @@
387
387
  "__TS__NumberIsFinite"
388
388
  ]
389
389
  },
390
+ "NumberIsInteger": {
391
+ "exports": [
392
+ "__TS__NumberIsInteger"
393
+ ],
394
+ "dependencies": [
395
+ "NumberIsFinite"
396
+ ]
397
+ },
390
398
  "NumberIsNaN": {
391
399
  "exports": [
392
400
  "__TS__NumberIsNaN"
@@ -74,6 +74,8 @@ function transformNumberConstructorCall(context, node, calledMethod) {
74
74
  const parameters = (0, call_1.transformArguments)(context, node.arguments);
75
75
  const methodName = calledMethod.name.text;
76
76
  switch (methodName) {
77
+ case "isInteger":
78
+ return (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.NumberIsInteger, node, ...parameters);
77
79
  case "isNaN":
78
80
  return (0, lualib_1.transformLuaLibFunction)(context, lualib_1.LuaLibFeature.NumberIsNaN, node, ...parameters);
79
81
  case "isFinite":
@@ -4,6 +4,7 @@ export declare enum AnnotationKind {
4
4
  CompileMembersOnly = "compileMembersOnly",
5
5
  NoResolution = "noResolution",
6
6
  NoSelf = "noSelf",
7
+ CustomName = "customName",
7
8
  NoSelfInFile = "noSelfInFile"
8
9
  }
9
10
  export interface Annotation {
@@ -8,6 +8,7 @@ var AnnotationKind;
8
8
  AnnotationKind["CompileMembersOnly"] = "compileMembersOnly";
9
9
  AnnotationKind["NoResolution"] = "noResolution";
10
10
  AnnotationKind["NoSelf"] = "noSelf";
11
+ AnnotationKind["CustomName"] = "customName";
11
12
  AnnotationKind["NoSelfInFile"] = "noSelfInFile";
12
13
  })(AnnotationKind || (exports.AnnotationKind = AnnotationKind = {}));
13
14
  const annotationValues = new Map(Object.values(AnnotationKind).map(k => [k.toLowerCase(), k]));
@@ -6,5 +6,5 @@ export declare enum ContextType {
6
6
  NonVoid = 2,
7
7
  Mixed = 3
8
8
  }
9
- export declare function getDeclarationContextType(context: TransformationContext, signatureDeclaration: ts.SignatureDeclaration): ContextType;
9
+ export declare function getCallContextType(context: TransformationContext, callExpression: ts.CallLikeExpression): ContextType;
10
10
  export declare function getFunctionContextType(context: TransformationContext, type: ts.Type): ContextType;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getFunctionContextType = exports.getDeclarationContextType = exports.ContextType = void 0;
3
+ exports.getFunctionContextType = exports.getCallContextType = exports.ContextType = void 0;
4
4
  const ts = require("typescript");
5
5
  const annotations_1 = require("./annotations");
6
6
  const typescript_1 = require("./typescript");
@@ -32,8 +32,33 @@ function getExplicitThisParameter(signatureDeclaration) {
32
32
  return param;
33
33
  }
34
34
  }
35
+ const callContextTypes = new WeakMap();
36
+ function getCallContextType(context, callExpression) {
37
+ const known = callContextTypes.get(callExpression);
38
+ if (known !== undefined)
39
+ return known;
40
+ const signature = context.checker.getResolvedSignature(callExpression);
41
+ const signatureDeclaration = signature === null || signature === void 0 ? void 0 : signature.getDeclaration();
42
+ let contextType = ContextType.None;
43
+ if (signatureDeclaration) {
44
+ contextType = computeDeclarationContextType(context, signatureDeclaration);
45
+ }
46
+ else {
47
+ // No signature declaration could be resolved, so instead try to see if the declaration is in a
48
+ // noSelfInFile file
49
+ const declarations = findRootDeclarations(context, callExpression);
50
+ contextType = declarations.some(d => (0, annotations_1.getFileAnnotations)(d.getSourceFile()).has(annotations_1.AnnotationKind.NoSelfInFile))
51
+ ? ContextType.Void
52
+ : context.options.noImplicitSelf
53
+ ? ContextType.Void
54
+ : ContextType.NonVoid;
55
+ }
56
+ callContextTypes.set(callExpression, contextType);
57
+ return contextType;
58
+ }
59
+ exports.getCallContextType = getCallContextType;
35
60
  const signatureDeclarationContextTypes = new WeakMap();
36
- function getDeclarationContextType(context, signatureDeclaration) {
61
+ function getSignatureContextType(context, signatureDeclaration) {
37
62
  const known = signatureDeclarationContextTypes.get(signatureDeclaration);
38
63
  if (known !== undefined)
39
64
  return known;
@@ -41,7 +66,29 @@ function getDeclarationContextType(context, signatureDeclaration) {
41
66
  signatureDeclarationContextTypes.set(signatureDeclaration, contextType);
42
67
  return contextType;
43
68
  }
44
- exports.getDeclarationContextType = getDeclarationContextType;
69
+ function findRootDeclarations(context, callExpression) {
70
+ var _a, _b;
71
+ const calledExpression = ts.isTaggedTemplateExpression(callExpression)
72
+ ? callExpression.tag
73
+ : ts.isJsxSelfClosingElement(callExpression)
74
+ ? callExpression.tagName
75
+ : ts.isJsxOpeningElement(callExpression)
76
+ ? callExpression.tagName
77
+ : callExpression.expression;
78
+ const calledSymbol = context.checker.getSymbolAtLocation(calledExpression);
79
+ if (calledSymbol === undefined)
80
+ return [];
81
+ return ((_b = (_a = calledSymbol.getDeclarations()) === null || _a === void 0 ? void 0 : _a.flatMap(d => {
82
+ var _a;
83
+ if (ts.isImportSpecifier(d)) {
84
+ const aliasSymbol = context.checker.getAliasedSymbol(calledSymbol);
85
+ return (_a = aliasSymbol.getDeclarations()) !== null && _a !== void 0 ? _a : [];
86
+ }
87
+ else {
88
+ return [d];
89
+ }
90
+ })) !== null && _b !== void 0 ? _b : []);
91
+ }
45
92
  function computeDeclarationContextType(context, signatureDeclaration) {
46
93
  const thisParameter = getExplicitThisParameter(signatureDeclaration);
47
94
  if (thisParameter) {
@@ -140,6 +187,6 @@ function computeFunctionContextType(context, type) {
140
187
  if (signatures.length === 0) {
141
188
  return ContextType.None;
142
189
  }
143
- return reduceContextTypes(signatures.flatMap(s => getSignatureDeclarations(context, s)).map(s => getDeclarationContextType(context, s)));
190
+ return reduceContextTypes(signatures.flatMap(s => getSignatureDeclarations(context, s)).map(s => getSignatureContextType(context, s)));
144
191
  }
145
192
  //# sourceMappingURL=function-context.js.map
@@ -16,6 +16,10 @@ interface FunctionDefinitionInfo {
16
16
  referencedSymbols: Map<lua.SymbolId, ts.Node[]>;
17
17
  definition?: lua.VariableDeclarationStatement | lua.AssignmentStatement;
18
18
  }
19
+ export declare enum LoopContinued {
20
+ WithGoto = 0,
21
+ WithRepeatBreak = 1
22
+ }
19
23
  export interface Scope {
20
24
  type: ScopeType;
21
25
  id: number;
@@ -24,7 +28,7 @@ export interface Scope {
24
28
  variableDeclarations?: lua.VariableDeclarationStatement[];
25
29
  functionDefinitions?: Map<lua.SymbolId, FunctionDefinitionInfo>;
26
30
  importStatements?: lua.Statement[];
27
- loopContinued?: boolean;
31
+ loopContinued?: LoopContinued;
28
32
  functionReturned?: boolean;
29
33
  }
30
34
  export interface HoistingResult {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.performHoisting = exports.separateHoistedStatements = exports.isFunctionScopeWithDefinition = exports.hasReferencedSymbol = exports.hasReferencedUndefinedLocalFunction = exports.addScopeVariableDeclaration = exports.findScope = exports.peekScope = exports.markSymbolAsReferencedInCurrentScopes = exports.walkScopesUp = exports.ScopeType = void 0;
3
+ exports.performHoisting = exports.separateHoistedStatements = exports.isFunctionScopeWithDefinition = exports.hasReferencedSymbol = exports.hasReferencedUndefinedLocalFunction = exports.addScopeVariableDeclaration = exports.findScope = exports.peekScope = exports.markSymbolAsReferencedInCurrentScopes = exports.walkScopesUp = exports.LoopContinued = exports.ScopeType = void 0;
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../LuaAST");
6
6
  const utils_1 = require("../../utils");
@@ -18,6 +18,11 @@ var ScopeType;
18
18
  ScopeType[ScopeType["Catch"] = 128] = "Catch";
19
19
  ScopeType[ScopeType["LoopInitializer"] = 256] = "LoopInitializer";
20
20
  })(ScopeType || (exports.ScopeType = ScopeType = {}));
21
+ var LoopContinued;
22
+ (function (LoopContinued) {
23
+ LoopContinued[LoopContinued["WithGoto"] = 0] = "WithGoto";
24
+ LoopContinued[LoopContinued["WithRepeatBreak"] = 1] = "WithRepeatBreak";
25
+ })(LoopContinued || (exports.LoopContinued = LoopContinued = {}));
21
26
  function* walkScopesUp(context) {
22
27
  const scopeStack = context.scopeStack;
23
28
  for (let i = scopeStack.length - 1; i >= 0; --i) {
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.transformContinueStatement = exports.transformBreakStatement = void 0;
4
4
  const CompilerOptions_1 = require("../../CompilerOptions");
5
5
  const lua = require("../../LuaAST");
6
- const diagnostics_1 = require("../utils/diagnostics");
7
6
  const scope_1 = require("../utils/scope");
8
7
  const transformBreakStatement = (breakStatement, context) => {
9
8
  void context;
@@ -12,16 +11,25 @@ const transformBreakStatement = (breakStatement, context) => {
12
11
  exports.transformBreakStatement = transformBreakStatement;
13
12
  const transformContinueStatement = (statement, context) => {
14
13
  var _a;
15
- if (context.luaTarget === CompilerOptions_1.LuaTarget.Universal ||
16
- context.luaTarget === CompilerOptions_1.LuaTarget.Lua50 ||
17
- context.luaTarget === CompilerOptions_1.LuaTarget.Lua51) {
18
- context.diagnostics.push((0, diagnostics_1.unsupportedForTarget)(statement, "Continue statement", context.luaTarget));
19
- }
20
14
  const scope = (0, scope_1.findScope)(context, scope_1.ScopeType.Loop);
15
+ const continuedWith = context.luaTarget === CompilerOptions_1.LuaTarget.Universal ||
16
+ context.luaTarget === CompilerOptions_1.LuaTarget.Lua50 ||
17
+ context.luaTarget === CompilerOptions_1.LuaTarget.Lua51
18
+ ? scope_1.LoopContinued.WithRepeatBreak
19
+ : scope_1.LoopContinued.WithGoto;
21
20
  if (scope) {
22
- scope.loopContinued = true;
21
+ scope.loopContinued = continuedWith;
22
+ }
23
+ const label = `__continue${(_a = scope === null || scope === void 0 ? void 0 : scope.id) !== null && _a !== void 0 ? _a : ""}`;
24
+ switch (continuedWith) {
25
+ case scope_1.LoopContinued.WithGoto:
26
+ return lua.createGotoStatement(label, statement);
27
+ case scope_1.LoopContinued.WithRepeatBreak:
28
+ return [
29
+ lua.createAssignmentStatement(lua.createIdentifier(label), lua.createBooleanLiteral(true), statement),
30
+ lua.createBreakStatement(statement),
31
+ ];
23
32
  }
24
- return lua.createGotoStatement(`__continue${(_a = scope === null || scope === void 0 ? void 0 : scope.id) !== null && _a !== void 0 ? _a : ""}`, statement);
25
33
  };
26
34
  exports.transformContinueStatement = transformContinueStatement;
27
35
  //# sourceMappingURL=break-continue.js.map
@@ -4,6 +4,6 @@ import { FunctionVisitor, TransformationContext } from "../context";
4
4
  export declare function validateArguments(context: TransformationContext, params: readonly ts.Expression[], signature?: ts.Signature): void;
5
5
  export declare function transformArguments(context: TransformationContext, params: readonly ts.Expression[], signature?: ts.Signature, callContext?: ts.Expression): lua.Expression[];
6
6
  export declare function transformCallAndArguments(context: TransformationContext, callExpression: ts.Expression, params: readonly ts.Expression[], signature?: ts.Signature, callContext?: ts.Expression): [lua.Expression, lua.Expression[]];
7
- export declare function transformContextualCallExpression(context: TransformationContext, node: ts.CallExpression | ts.TaggedTemplateExpression, args: ts.Expression[] | ts.NodeArray<ts.Expression>, signature?: ts.Signature): lua.Expression;
7
+ export declare function transformContextualCallExpression(context: TransformationContext, node: ts.CallExpression | ts.TaggedTemplateExpression, args: ts.Expression[] | ts.NodeArray<ts.Expression>): lua.Expression;
8
8
  export declare const transformCallExpression: FunctionVisitor<ts.CallExpression>;
9
9
  export declare function getCalledExpression(node: ts.CallExpression): ts.Expression;
@@ -17,6 +17,7 @@ const preceding_statements_1 = require("../utils/preceding-statements");
17
17
  const optional_chaining_1 = require("./optional-chaining");
18
18
  const import_1 = require("./modules/import");
19
19
  const call_extension_1 = require("./language-extensions/call-extension");
20
+ const identifier_1 = require("./identifier");
20
21
  function validateArguments(context, params, signature) {
21
22
  if (!signature || signature.parameters.length < params.length) {
22
23
  return;
@@ -77,19 +78,25 @@ function transformElementAccessCall(context, left, transformedArguments, argPrec
77
78
  }
78
79
  return lua.createCallExpression(index, [selfIdentifier, ...transformedArguments]);
79
80
  }
80
- function transformContextualCallExpression(context, node, args, signature) {
81
+ function transformContextualCallExpression(context, node, args) {
81
82
  if (ts.isOptionalChain(node)) {
82
83
  return (0, optional_chaining_1.transformOptionalChain)(context, node);
83
84
  }
84
85
  const left = ts.isCallExpression(node) ? getCalledExpression(node) : node.tag;
85
- let { precedingStatements: argPrecedingStatements, result: transformedArguments } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformArguments(context, args, signature));
86
+ let { precedingStatements: argPrecedingStatements, result: transformedArguments } = (0, preceding_statements_1.transformInPrecedingStatementScope)(context, () => transformArguments(context, args));
86
87
  if (ts.isPropertyAccessExpression(left) &&
87
88
  ts.isIdentifier(left.name) &&
88
89
  (0, safe_names_1.isValidLuaIdentifier)(left.name.text, context.options) &&
89
90
  argPrecedingStatements.length === 0) {
90
91
  // table:name()
91
92
  const table = context.transformExpression(left.expression);
92
- return lua.createMethodCallExpression(table, lua.createIdentifier(left.name.text, left.name), transformedArguments, node);
93
+ let name = left.name.text;
94
+ const symbol = context.checker.getSymbolAtLocation(left);
95
+ const customName = (0, identifier_1.getCustomNameFromSymbol)(symbol);
96
+ if (customName) {
97
+ name = customName;
98
+ }
99
+ return lua.createMethodCallExpression(table, lua.createIdentifier(name, left.name), transformedArguments, node);
93
100
  }
94
101
  else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) {
95
102
  if ((0, typescript_1.isExpressionWithEvaluationEffect)(left.expression)) {
@@ -119,10 +126,9 @@ function transformPropertyCall(context, node, calledMethod) {
119
126
  const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis());
120
127
  return lua.createCallExpression(context.transformExpression(node.expression), parameters, node);
121
128
  }
122
- const signatureDeclaration = signature === null || signature === void 0 ? void 0 : signature.getDeclaration();
123
- if (!signatureDeclaration || (0, function_context_1.getDeclarationContextType)(context, signatureDeclaration) !== function_context_1.ContextType.Void) {
129
+ if ((0, function_context_1.getCallContextType)(context, node) !== function_context_1.ContextType.Void) {
124
130
  // table:name()
125
- return transformContextualCallExpression(context, node, node.arguments, signature);
131
+ return transformContextualCallExpression(context, node, node.arguments);
126
132
  }
127
133
  else {
128
134
  // table.name()
@@ -131,15 +137,13 @@ function transformPropertyCall(context, node, calledMethod) {
131
137
  }
132
138
  }
133
139
  function transformElementCall(context, node) {
134
- const signature = context.checker.getResolvedSignature(node);
135
- const signatureDeclaration = signature === null || signature === void 0 ? void 0 : signature.getDeclaration();
136
- if (!signatureDeclaration || (0, function_context_1.getDeclarationContextType)(context, signatureDeclaration) !== function_context_1.ContextType.Void) {
140
+ if ((0, function_context_1.getCallContextType)(context, node) !== function_context_1.ContextType.Void) {
137
141
  // A contextual parameter must be given to this call expression
138
- return transformContextualCallExpression(context, node, node.arguments, signature);
142
+ return transformContextualCallExpression(context, node, node.arguments);
139
143
  }
140
144
  else {
141
145
  // No context
142
- const [expression, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature);
146
+ const [expression, parameters] = transformCallAndArguments(context, node.expression, node.arguments);
143
147
  return lua.createCallExpression(expression, parameters, node);
144
148
  }
145
149
  }
@@ -179,7 +183,7 @@ const transformCallExpression = (node, context) => {
179
183
  }
180
184
  let callPath;
181
185
  let parameters;
182
- const isContextualCall = isContextualCallExpression(context, signature);
186
+ const isContextualCall = (0, function_context_1.getCallContextType)(context, node) !== function_context_1.ContextType.Void;
183
187
  if (!isContextualCall) {
184
188
  [callPath, parameters] = transformCallAndArguments(context, calledExpression, node.arguments, signature);
185
189
  }
@@ -196,13 +200,6 @@ const transformCallExpression = (node, context) => {
196
200
  return wrapResultInTable ? (0, lua_ast_1.wrapInTable)(callExpression) : callExpression;
197
201
  };
198
202
  exports.transformCallExpression = transformCallExpression;
199
- function isContextualCallExpression(context, signature) {
200
- const declaration = signature === null || signature === void 0 ? void 0 : signature.getDeclaration();
201
- if (!declaration) {
202
- return !context.options.noImplicitSelf;
203
- }
204
- return (0, function_context_1.getDeclarationContextType)(context, declaration) !== function_context_1.ContextType.Void;
205
- }
206
203
  function getCalledExpression(node) {
207
204
  return ts.skipOuterExpressions(node.expression);
208
205
  }
@@ -17,6 +17,7 @@ const setup_1 = require("./setup");
17
17
  const CompilerOptions_1 = require("../../../CompilerOptions");
18
18
  const preceding_statements_1 = require("../../utils/preceding-statements");
19
19
  const decorators_2 = require("./decorators");
20
+ const typescript_1 = require("../../utils/typescript");
20
21
  const transformClassDeclaration = (declaration, context) => {
21
22
  // If declaration is a default export, transform to export variable assignment instead
22
23
  if ((0, export_1.hasDefaultExportModifier)(declaration)) {
@@ -180,7 +181,14 @@ const transformSuperExpression = (expression, context) => {
180
181
  // Use "className.____super" if the base is not a simple identifier
181
182
  baseClassName = lua.createTableIndexExpression(className, lua.createStringLiteral("____super"), expression);
182
183
  }
183
- return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype"));
184
+ const f = (0, typescript_1.findFirstNodeAbove)(expression, ts.isFunctionLike);
185
+ if (f && ts.canHaveModifiers(f) && (0, utils_1.isStaticNode)(f)) {
186
+ // In static method, don't add prototype to super call
187
+ return baseClassName;
188
+ }
189
+ else {
190
+ return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype"));
191
+ }
184
192
  };
185
193
  exports.transformSuperExpression = transformSuperExpression;
186
194
  //# sourceMappingURL=index.js.map
@@ -2,5 +2,6 @@ import * as ts from "typescript";
2
2
  import * as lua from "../../LuaAST";
3
3
  import { FunctionVisitor, TransformationContext } from "../context";
4
4
  export declare function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier;
5
+ export declare function getCustomNameFromSymbol(symbol?: ts.Symbol): undefined | string;
5
6
  export declare function transformIdentifierWithSymbol(context: TransformationContext, node: ts.Identifier, symbol: ts.Symbol | undefined): lua.Expression;
6
7
  export declare const transformIdentifierExpression: FunctionVisitor<ts.Identifier>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformIdentifierExpression = exports.transformIdentifierWithSymbol = exports.transformIdentifier = void 0;
3
+ exports.transformIdentifierExpression = exports.transformIdentifierWithSymbol = exports.getCustomNameFromSymbol = exports.transformIdentifier = void 0;
4
4
  const ts = require("typescript");
5
5
  const lua = require("../../LuaAST");
6
6
  const builtins_1 = require("../builtins");
@@ -15,10 +15,33 @@ const typescript_1 = require("../utils/typescript");
15
15
  const language_extensions_1 = require("../utils/language-extensions");
16
16
  const call_extension_1 = require("./language-extensions/call-extension");
17
17
  const identifier_1 = require("./language-extensions/identifier");
18
+ const annotations_1 = require("../utils/annotations");
18
19
  function transformIdentifier(context, identifier) {
19
20
  return transformNonValueIdentifier(context, identifier, context.checker.getSymbolAtLocation(identifier));
20
21
  }
21
22
  exports.transformIdentifier = transformIdentifier;
23
+ function getCustomNameFromSymbol(symbol) {
24
+ let retVal;
25
+ if (symbol) {
26
+ const declarations = symbol.getDeclarations();
27
+ if (declarations) {
28
+ let customNameAnnotation = undefined;
29
+ for (const declaration of declarations) {
30
+ const nodeAnnotations = (0, annotations_1.getNodeAnnotations)(declaration);
31
+ const foundAnnotation = nodeAnnotations.get(annotations_1.AnnotationKind.CustomName);
32
+ if (foundAnnotation) {
33
+ customNameAnnotation = foundAnnotation;
34
+ break;
35
+ }
36
+ }
37
+ if (customNameAnnotation) {
38
+ retVal = customNameAnnotation.args[0];
39
+ }
40
+ }
41
+ }
42
+ return retVal;
43
+ }
44
+ exports.getCustomNameFromSymbol = getCustomNameFromSymbol;
22
45
  function transformNonValueIdentifier(context, identifier, symbol) {
23
46
  if ((0, optional_chaining_1.isOptionalContinuation)(identifier)) {
24
47
  const result = lua.createIdentifier(identifier.text, undefined, context_1.tempSymbolId);
@@ -48,9 +71,10 @@ function transformNonValueIdentifier(context, identifier, symbol) {
48
71
  return (0, promise_1.createPromiseIdentifier)(identifier);
49
72
  }
50
73
  }
51
- const text = (0, safe_names_1.hasUnsafeIdentifierName)(context, identifier, symbol)
52
- ? (0, safe_names_1.createSafeName)(identifier.text)
53
- : identifier.text;
74
+ let text = (0, safe_names_1.hasUnsafeIdentifierName)(context, identifier, symbol) ? (0, safe_names_1.createSafeName)(identifier.text) : identifier.text;
75
+ const customName = getCustomNameFromSymbol(symbol);
76
+ if (customName)
77
+ text = customName;
54
78
  const symbolId = (0, symbols_1.getIdentifierSymbolId)(context, identifier, symbol);
55
79
  return lua.createIdentifier(text, identifier, symbolId, identifier.text);
56
80
  }
@@ -16,13 +16,22 @@ function transformLoopBody(context, loop) {
16
16
  const body = (0, scope_1.performHoisting)(context, (0, block_1.transformBlockOrStatement)(context, loop.statement));
17
17
  const scope = context.popScope();
18
18
  const scopeId = scope.id;
19
- if (!scope.loopContinued) {
20
- return body;
19
+ switch (scope.loopContinued) {
20
+ case undefined:
21
+ return body;
22
+ case scope_1.LoopContinued.WithGoto:
23
+ return [lua.createDoStatement(body), lua.createLabelStatement(`__continue${scopeId}`)];
24
+ case scope_1.LoopContinued.WithRepeatBreak:
25
+ const identifier = lua.createIdentifier(`__continue${scopeId}`);
26
+ const literalTrue = lua.createBooleanLiteral(true);
27
+ return [
28
+ lua.createDoStatement([
29
+ lua.createVariableDeclarationStatement(identifier),
30
+ lua.createRepeatStatement(lua.createBlock([...body, lua.createAssignmentStatement(identifier, literalTrue)]), literalTrue),
31
+ lua.createIfStatement(lua.createUnaryExpression(identifier, lua.SyntaxKind.NotOperator), lua.createBlock([lua.createBreakStatement()])),
32
+ ]),
33
+ ];
21
34
  }
22
- const baseResult = [lua.createDoStatement(body)];
23
- const continueLabel = lua.createLabelStatement(`__continue${scopeId}`);
24
- baseResult.push(continueLabel);
25
- return baseResult;
26
35
  }
27
36
  exports.transformLoopBody = transformLoopBody;
28
37
  function getVariableDeclarationBinding(context, node) {
@@ -66,14 +66,12 @@ const transformTaggedTemplateExpression = (expression, context) => {
66
66
  ]);
67
67
  expressions.unshift(stringObject);
68
68
  // Evaluate if there is a self parameter to be used.
69
- const signature = context.checker.getResolvedSignature(expression);
70
- const signatureDeclaration = signature === null || signature === void 0 ? void 0 : signature.getDeclaration();
71
- const useSelfParameter = signatureDeclaration && (0, function_context_1.getDeclarationContextType)(context, signatureDeclaration) !== function_context_1.ContextType.Void;
69
+ const useSelfParameter = (0, function_context_1.getCallContextType)(context, expression) !== function_context_1.ContextType.Void;
72
70
  if (useSelfParameter) {
73
- return (0, call_1.transformContextualCallExpression)(context, expression, expressions, signature);
71
+ return (0, call_1.transformContextualCallExpression)(context, expression, expressions);
74
72
  }
75
73
  // Argument evaluation.
76
- const callArguments = (0, call_1.transformArguments)(context, expressions, signature);
74
+ const callArguments = (0, call_1.transformArguments)(context, expressions);
77
75
  const leftHandSideExpression = context.transformExpression(expression.tag);
78
76
  return lua.createCallExpression(leftHandSideExpression, callArguments);
79
77
  };
@@ -29,6 +29,14 @@ export interface Plugin {
29
29
  * This function is called after translating the input program to Lua, after resolving dependencies and after bundling.
30
30
  */
31
31
  beforeEmit?: (program: ts.Program, options: CompilerOptions, emitHost: EmitHost, result: EmitFile[]) => ts.Diagnostic[] | void;
32
+ /**
33
+ * This function is called after translating the input program to Lua, after resolving dependencies, after bundling and writing files to disk.
34
+ */
35
+ afterEmit?: (program: ts.Program, options: CompilerOptions, emitHost: EmitHost, result: EmitFile[]) => ts.Diagnostic[] | void;
36
+ /**
37
+ * This function is called when trying to resolve the .lua file corresponding to a Lua require statement. Allows you to provide
38
+ * your own module resolution logic. If return value is undefined, regular module resolution is done.
39
+ */
32
40
  moduleResolution?: (moduleIdentifier: string, requiringFile: string, options: CompilerOptions, emitHost: EmitHost) => string | undefined;
33
41
  }
34
42
  export declare function getPlugins(program: ts.Program): {
@@ -31,7 +31,7 @@ class Transpiler {
31
31
  };
32
32
  }
33
33
  emitFiles(program, plugins, emitPlan, writeFile) {
34
- var _a, _b;
34
+ var _a, _b, _c;
35
35
  performance.startSection("emit");
36
36
  const options = program.getCompilerOptions();
37
37
  if (options.tstlVerbose) {
@@ -54,6 +54,12 @@ class Transpiler {
54
54
  writeFile(outputPath + ".map", sourceMap, emitBOM, undefined, sourceFiles);
55
55
  }
56
56
  }
57
+ for (const plugin of plugins) {
58
+ if (plugin.afterEmit) {
59
+ const afterEmitPluginDiagnostics = (_c = plugin.afterEmit(program, options, this.emitHost, emitPlan)) !== null && _c !== void 0 ? _c : [];
60
+ diagnostics.push(...afterEmitPluginDiagnostics);
61
+ }
62
+ }
57
63
  if (options.tstlVerbose) {
58
64
  console.log("Emit finished!");
59
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typescript-to-lua",
3
- "version": "1.20.1",
3
+ "version": "1.22.0",
4
4
  "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!",
5
5
  "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua",
6
6
  "homepage": "https://typescripttolua.github.io/",