Skip to content

Commit f23ea3e

Browse files
authored
Correctly place class member preceding instances in the constructor always (#1211)
1 parent 3f76d2c commit f23ea3e

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as ts from "typescript";
22
import * as lua from "../../../../LuaAST";
33
import { TransformationContext } from "../../../context";
44
import { createSelfIdentifier } from "../../../utils/lua-ast";
5-
import { transformInPrecedingStatementScope } from "../../../utils/preceding-statements";
65
import { popScope, pushScope, ScopeType } from "../../../utils/scope";
76
import { transformFunctionBodyContent, transformFunctionBodyHeader, transformParameters } from "../../function";
87
import { transformIdentifier } from "../../identifier";
@@ -44,9 +43,7 @@ export function transformConstructorDeclaration(
4443
// Check for field declarations in constructor
4544
const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined);
4645

47-
const [fieldsPrecedingStatements, classInstanceFields] = transformInPrecedingStatementScope(context, () =>
48-
transformClassInstanceFields(context, instanceFields)
49-
);
46+
const classInstanceFields = transformClassInstanceFields(context, instanceFields);
5047

5148
// If there are field initializers and the first statement is a super call,
5249
// move super call between default assignments and initializers
@@ -81,7 +78,6 @@ export function transformConstructorDeclaration(
8178
// else { TypeScript error: A parameter property may not be declared using a binding pattern }
8279
}
8380

84-
bodyWithFieldInitializers.push(...fieldsPrecedingStatements);
8581
bodyWithFieldInitializers.push(...classInstanceFields);
8682

8783
bodyWithFieldInitializers.push(...body);

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as ts from "typescript";
22
import * as lua from "../../../../LuaAST";
33
import { TransformationContext } from "../../../context";
44
import { createSelfIdentifier } from "../../../utils/lua-ast";
5+
import { transformInPrecedingStatementScope } from "../../../utils/preceding-statements";
56
import { transformPropertyName } from "../../literal";
67
import { createDecoratingExpression, transformDecoratorExpression } from "../decorators";
78
import { transformMemberExpressionOwnerName } from "./method";
@@ -30,18 +31,22 @@ export function transformClassInstanceFields(
3031
const statements: lua.Statement[] = [];
3132

3233
for (const f of instanceFields) {
33-
// Get identifier
34-
const fieldName = transformPropertyName(context, f.name);
34+
const [precedingStatements, statement] = transformInPrecedingStatementScope(context, () => {
35+
// Get identifier
36+
const fieldName = transformPropertyName(context, f.name);
3537

36-
const value = f.initializer ? context.transformExpression(f.initializer) : undefined;
38+
const value = f.initializer ? context.transformExpression(f.initializer) : undefined;
3739

38-
// self[fieldName]
39-
const selfIndex = lua.createTableIndexExpression(createSelfIdentifier(), fieldName);
40+
// self[fieldName]
41+
const selfIndex = lua.createTableIndexExpression(createSelfIdentifier(), fieldName);
4042

41-
// self[fieldName] = value
42-
const assignClassField = lua.createAssignmentStatement(selfIndex, value, f);
43+
// self[fieldName] = value
44+
const assignClassField = lua.createAssignmentStatement(selfIndex, value, f);
4345

44-
statements.push(assignClassField);
46+
return assignClassField;
47+
});
48+
49+
statements.push(...precedingStatements, statement);
4550
}
4651

4752
return statements;

test/unit/precedingStatements.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,3 +635,14 @@ test("class member initializers", () => {
635635
return [inst.myField, inst.foo];
636636
`.expectToMatchJsResult();
637637
});
638+
639+
test("class member initializers in extended class", () => {
640+
util.testFunction`
641+
class A {}
642+
class MyClass extends A {
643+
myField = false ?? true;
644+
}
645+
const inst = new MyClass();
646+
return inst.myField;
647+
`.expectToMatchJsResult();
648+
});

0 commit comments

Comments
 (0)