Skip to content

Commit 1093e8f

Browse files
Update to TypeScript 4 (#914)
* Print numbers overflowing the float limit as math.huge * Update TypeScript * Equalize Object.assign change * Use ts-ignore instead of Object.assign * Update dependencies, fix minor issues * Add package-lock.json changes * Update package.json Co-authored-by: ark120202 <ark120202@gmail.com> * Remove some skipped accessors tests, TypeScript no longer accepts that code * Rename transformFunctionBodyStatements -> transformFunctionBodyContent * Slight refactor for return.ts Co-authored-by: ark120202 <ark120202@gmail.com>
1 parent 8dd12a9 commit 1093e8f

File tree

9 files changed

+365
-184
lines changed

9 files changed

+365
-184
lines changed

package-lock.json

Lines changed: 283 additions & 50 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"dependencies": {
3939
"resolve": "^1.15.1",
4040
"source-map": "^0.7.3",
41-
"typescript": "^3.9.2"
41+
"typescript": ">=4.0.2"
4242
},
4343
"devDependencies": {
4444
"@types/fs-extra": "^8.1.0",
@@ -47,7 +47,7 @@
4747
"@types/node": "^13.7.7",
4848
"@types/resolve": "1.14.0",
4949
"@typescript-eslint/eslint-plugin": "^2.31.0",
50-
"@typescript-eslint/parser": "^2.31.0",
50+
"@typescript-eslint/parser": "^4.1.0",
5151
"eslint": "^6.8.0",
5252
"eslint-plugin-import": "^2.20.1",
5353
"eslint-plugin-jest": "^23.8.2",
@@ -58,7 +58,7 @@
5858
"jest-circus": "^25.1.0",
5959
"lua-types": "^2.8.0",
6060
"prettier": "^2.0.5",
61-
"ts-jest": "^26.0.0",
61+
"ts-jest": "^26.3.0",
6262
"ts-node": "^8.6.2"
6363
}
6464
}

src/transformation/utils/assignment-validation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ export function validateAssignment(
3434

3535
validateFunctionAssignment(context, node, fromType, toType, toName);
3636

37-
const fromTypeNode = context.checker.typeToTypeNode(fromType);
38-
const toTypeNode = context.checker.typeToTypeNode(toType);
37+
const fromTypeNode = context.checker.typeToTypeNode(fromType, undefined, undefined);
38+
const toTypeNode = context.checker.typeToTypeNode(toType, undefined, undefined);
3939
if (!fromTypeNode || !toTypeNode) {
4040
return;
4141
}

src/transformation/visitors/binary-expression/compound.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type CompoundAssignmentToken =
4848
| ts.SyntaxKind.GreaterThanGreaterThanToken
4949
| ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken;
5050

51-
const compoundToAssignmentTokens: Record<ts.CompoundAssignmentOperator, CompoundAssignmentToken> = {
51+
const compoundToAssignmentTokens: Partial<Record<ts.CompoundAssignmentOperator, CompoundAssignmentToken>> = {
5252
[ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken,
5353
[ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken,
5454
[ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken,
@@ -66,8 +66,9 @@ const compoundToAssignmentTokens: Record<ts.CompoundAssignmentOperator, Compound
6666
export const isCompoundAssignmentToken = (token: ts.BinaryOperator): token is ts.CompoundAssignmentOperator =>
6767
token in compoundToAssignmentTokens;
6868

69-
export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken =>
70-
compoundToAssignmentTokens[token];
69+
export const unwrapCompoundAssignmentToken = (
70+
token: ts.CompoundAssignmentOperator
71+
): CompoundAssignmentToken | undefined => compoundToAssignmentTokens[token];
7172

7273
export function transformCompoundAssignmentExpression(
7374
context: TransformationContext,

src/transformation/visitors/binary-expression/index.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as ts from "typescript";
22
import * as lua from "../../../LuaAST";
33
import { FunctionVisitor, TransformationContext } from "../../context";
44
import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations";
5-
import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics";
5+
import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf, unsupportedNodeKind } from "../../utils/diagnostics";
66
import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast";
77
import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib";
88
import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript";
@@ -77,14 +77,13 @@ export const transformBinaryExpression: FunctionVisitor<ts.BinaryExpression> = (
7777
}
7878

7979
if (isCompoundAssignmentToken(operator)) {
80-
return transformCompoundAssignmentExpression(
81-
context,
82-
node,
83-
node.left,
84-
node.right,
85-
unwrapCompoundAssignmentToken(operator),
86-
false
87-
);
80+
const token = unwrapCompoundAssignmentToken(operator);
81+
if (!token) {
82+
context.diagnostics.push(unsupportedNodeKind(node, operator));
83+
return lua.createNilLiteral(node);
84+
}
85+
86+
return transformCompoundAssignmentExpression(context, node, node.left, node.right, token, false);
8887
}
8988

9089
switch (operator) {
@@ -157,13 +156,13 @@ export function transformBinaryExpressionStatement(
157156

158157
if (isCompoundAssignmentToken(operator)) {
159158
// +=, -=, etc...
160-
return transformCompoundAssignmentStatement(
161-
context,
162-
expression,
163-
expression.left,
164-
expression.right,
165-
unwrapCompoundAssignmentToken(operator)
166-
);
159+
const token = unwrapCompoundAssignmentToken(operator);
160+
if (!token) {
161+
context.diagnostics.push(unsupportedNodeKind(node, operator));
162+
return;
163+
}
164+
165+
return transformCompoundAssignmentStatement(context, expression, expression.left, expression.right, token);
167166
} else if (operator === ts.SyntaxKind.EqualsToken) {
168167
return transformAssignmentStatement(context, expression as ts.AssignmentExpression<ts.EqualsToken>);
169168
} else if (operator === ts.SyntaxKind.CommaToken) {

src/transformation/visitors/class/members/constructor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as lua from "../../../../LuaAST";
33
import { TransformationContext } from "../../../context";
44
import { createSelfIdentifier } from "../../../utils/lua-ast";
55
import { popScope, pushScope, ScopeType } from "../../../utils/scope";
6-
import { transformFunctionBodyHeader, transformFunctionBodyStatements, transformParameters } from "../../function";
6+
import { transformFunctionBodyHeader, transformFunctionBodyContent, transformParameters } from "../../function";
77
import { transformIdentifier } from "../../identifier";
88
import { transformClassInstanceFields } from "./fields";
99

@@ -28,7 +28,7 @@ export function transformConstructorDeclaration(
2828

2929
// Transform body
3030
const scope = pushScope(context, ScopeType.Function);
31-
const body = transformFunctionBodyStatements(context, statement.body);
31+
const body = transformFunctionBodyContent(context, statement.body);
3232

3333
const [params, dotsLiteral, restParamName] = transformParameters(
3434
context,

src/transformation/visitors/function.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib";
1616
import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope";
1717
import { transformIdentifier } from "./identifier";
18+
import { transformExpressionBodyToReturnStatement } from "./return";
1819
import { transformBindingPattern } from "./variable-declaration";
1920

2021
function transformParameterDefaultValueDeclaration(
@@ -52,7 +53,12 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l
5253
return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarargType(context, r));
5354
}
5455

55-
export function transformFunctionBodyStatements(context: TransformationContext, body: ts.Block): lua.Statement[] {
56+
export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] {
57+
if (!ts.isBlock(body)) {
58+
const returnStatement = transformExpressionBodyToReturnStatement(context, body);
59+
return [returnStatement];
60+
}
61+
5662
const bodyStatements = performHoisting(context, context.transformStatements(body.statements));
5763
return bodyStatements;
5864
}
@@ -107,11 +113,11 @@ export function transformFunctionBodyHeader(
107113
export function transformFunctionBody(
108114
context: TransformationContext,
109115
parameters: ts.NodeArray<ts.ParameterDeclaration>,
110-
body: ts.Block,
116+
body: ts.ConciseBody,
111117
spreadIdentifier?: lua.Identifier
112118
): [lua.Statement[], Scope] {
113119
const scope = pushScope(context, ScopeType.Function);
114-
const bodyStatements = transformFunctionBodyStatements(context, body);
120+
const bodyStatements = transformFunctionBodyContent(context, body);
115121
const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier);
116122
popScope(context);
117123
return [[...headerStatements, ...bodyStatements], scope];
@@ -184,18 +190,13 @@ export function transformFunctionToExpression(
184190
flags |= lua.FunctionExpressionFlags.Declaration;
185191
}
186192

187-
let body: ts.Block;
188-
if (ts.isBlock(node.body)) {
189-
body = node.body;
190-
} else {
191-
const returnExpression = ts.createReturn(node.body);
192-
body = ts.createBlock([returnExpression]);
193-
returnExpression.parent = body;
194-
if (node.body) body.parent = node.body.parent;
195-
}
196-
197193
const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext);
198-
const [transformedBody, functionScope] = transformFunctionBody(context, node.parameters, body, spreadIdentifier);
194+
const [transformedBody, functionScope] = transformFunctionBody(
195+
context,
196+
node.parameters,
197+
node.body,
198+
spreadIdentifier
199+
);
199200
const functionExpression = lua.createFunctionExpression(
200201
lua.createBlock(transformedBody),
201202
paramNames,

src/transformation/visitors/return.ts

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,51 @@
11
import * as ts from "typescript";
22
import * as lua from "../../LuaAST";
3-
import { FunctionVisitor } from "../context";
3+
import { FunctionVisitor, TransformationContext } from "../context";
44
import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations";
55
import { validateAssignment } from "../utils/assignment-validation";
66
import { createUnpackCall, wrapInTable } from "../utils/lua-ast";
77
import { ScopeType, walkScopesUp } from "../utils/scope";
88
import { isArrayType } from "../utils/typescript";
99

10+
function transformExpressionsInReturn(
11+
context: TransformationContext,
12+
node: ts.Expression,
13+
insideTryCatch: boolean
14+
): lua.Expression[] {
15+
if (!isInTupleReturnFunction(context, node)) {
16+
return [context.transformExpression(node)];
17+
}
18+
19+
let results: lua.Expression[];
20+
const expressionType = context.checker.getTypeAtLocation(node);
21+
22+
// Parent function is a TupleReturn function
23+
if (ts.isArrayLiteralExpression(node)) {
24+
// If return expression is an array literal, leave out brackets.
25+
results = node.elements.map(e => context.transformExpression(e));
26+
} else if (!isTupleReturnCall(context, node) && isArrayType(context, expressionType)) {
27+
// If return expression is an array-type and not another TupleReturn call, unpack it
28+
results = [createUnpackCall(context, context.transformExpression(node), node)];
29+
} else {
30+
results = [context.transformExpression(node)];
31+
}
32+
33+
// Wrap tupleReturn results when returning inside try/catch
34+
if (insideTryCatch) {
35+
results = [wrapInTable(...results)];
36+
}
37+
38+
return results;
39+
}
40+
41+
export function transformExpressionBodyToReturnStatement(
42+
context: TransformationContext,
43+
node: ts.Expression
44+
): lua.Statement {
45+
const expressions = transformExpressionsInReturn(context, node, false);
46+
return lua.createReturnStatement(expressions, node);
47+
}
48+
1049
export const transformReturnStatement: FunctionVisitor<ts.ReturnStatement> = (statement, context) => {
1150
// Bubble up explicit return flag and check if we're inside a try/catch block
1251
let insideTryCatch = false;
@@ -29,27 +68,7 @@ export const transformReturnStatement: FunctionVisitor<ts.ReturnStatement> = (st
2968
validateAssignment(context, statement, expressionType, returnType);
3069
}
3170

32-
if (isInTupleReturnFunction(context, statement)) {
33-
// Parent function is a TupleReturn function
34-
if (ts.isArrayLiteralExpression(statement.expression)) {
35-
// If return expression is an array literal, leave out brackets.
36-
results = statement.expression.elements.map(e => context.transformExpression(e));
37-
} else if (!isTupleReturnCall(context, statement.expression) && isArrayType(context, expressionType)) {
38-
// If return expression is an array-type and not another TupleReturn call, unpack it
39-
results = [
40-
createUnpackCall(context, context.transformExpression(statement.expression), statement.expression),
41-
];
42-
} else {
43-
results = [context.transformExpression(statement.expression)];
44-
}
45-
46-
// Wrap tupleReturn results when returning inside try/catch
47-
if (insideTryCatch) {
48-
results = [wrapInTable(...results)];
49-
}
50-
} else {
51-
results = [context.transformExpression(statement.expression)];
52-
}
71+
results = transformExpressionsInReturn(context, statement.expression, insideTryCatch);
5372
} else {
5473
// Empty return
5574
results = [];

test/unit/classes/accessors.spec.ts

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -23,34 +23,6 @@ test("get accessor in base class", () => {
2323
`.expectToMatchJsResult();
2424
});
2525

26-
test.skip("get accessor override", () => {
27-
util.testFunction`
28-
class Foo {
29-
_foo = "foo";
30-
foo = "foo";
31-
}
32-
class Bar extends Foo {
33-
get foo() { return this._foo + "bar"; }
34-
}
35-
const b = new Bar();
36-
return b.foo;
37-
`.expectToMatchJsResult();
38-
});
39-
40-
test.skip("get accessor overridden", () => {
41-
util.testFunction`
42-
class Foo {
43-
_foo = "foo";
44-
get foo() { return this._foo; }
45-
}
46-
class Bar extends Foo {
47-
foo = "bar";
48-
}
49-
const b = new Bar();
50-
return b.foo;
51-
`.expectToMatchJsResult();
52-
});
53-
5426
test("get accessor override accessor", () => {
5527
util.testFunction`
5628
class Foo {
@@ -125,37 +97,6 @@ test("set accessor in base class", () => {
12597
`.expectToMatchJsResult();
12698
});
12799

128-
test("set accessor override", () => {
129-
util.testFunction`
130-
class Foo {
131-
_foo = "foo";
132-
foo = "foo";
133-
}
134-
class Bar extends Foo {
135-
set foo(val: string) { this._foo = val; }
136-
}
137-
const b = new Bar();
138-
b.foo = "bar"
139-
return b._foo;
140-
`.expectToMatchJsResult();
141-
});
142-
143-
test("set accessor overridden", () => {
144-
util.testFunction`
145-
class Foo {
146-
_foo = "baz";
147-
set foo(val: string) { this._foo = val; }
148-
}
149-
class Bar extends Foo {
150-
foo = "foo"; // triggers base class setter
151-
}
152-
const b = new Bar();
153-
const fooOriginal = b._foo;
154-
b.foo = "bar"
155-
return fooOriginal + b._foo;
156-
`.expectToMatchJsResult();
157-
});
158-
159100
test("set accessor override accessor", () => {
160101
util.testFunction`
161102
class Foo {
@@ -250,19 +191,6 @@ test("static get accessor override", () => {
250191
`.expectToMatchJsResult();
251192
});
252193

253-
test.skip("static get accessor overridden", () => {
254-
util.testFunction`
255-
class Foo {
256-
static _foo = "foo";
257-
static get foo() { return this._foo; }
258-
}
259-
class Bar extends Foo {
260-
static foo = "bar";
261-
}
262-
return Bar.foo;
263-
`.expectToMatchJsResult();
264-
});
265-
266194
test("static get accessor override accessor", () => {
267195
util.testFunction`
268196
class Foo {

0 commit comments

Comments
 (0)