Skip to content

Commit 282da23

Browse files
authored
Bugfix/anonymous class name (#810)
* Updated tests to new TestBuilder * Updated classes/classes tests to new TestBuilder * Fixed exported class super call test * Fixed inconsistency between reflection class names of JS and Lua * Reverted unique default class name change * Reverted change and changed tests to use testModule instead of setTsHeader * Fixed some remaining merge issues * Added gitattributes * Refactored class transformation functions * Also fixed #584, moved getReflectionName to setup and some other minor changes * Moved getReflectionClassName to setup completely * Moved tests
1 parent f366595 commit 282da23

File tree

6 files changed

+292
-360
lines changed

6 files changed

+292
-360
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text eol=lf

src/transformation/visitors/class/index.ts

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import {
77
extensionAndMetaExtensionConflict,
88
extensionCannotExport,
99
extensionCannotExtend,
10-
metaExtensionMissingExtends,
11-
luaTableMustBeAmbient,
1210
luaTableCannotBeExtended,
11+
luaTableMustBeAmbient,
12+
metaExtensionMissingExtends,
1313
} from "../../utils/diagnostics";
1414
import {
1515
createDefaultExportIdentifier,
@@ -21,7 +21,6 @@ import {
2121
import {
2222
createImmediatelyInvokedFunctionExpression,
2323
createSelfIdentifier,
24-
OneToManyVisitorResult,
2524
unwrapVisitorResult,
2625
} from "../../utils/lua-ast";
2726
import { createSafeName, isUnsafeName } from "../../utils/safe-names";
@@ -38,25 +37,29 @@ import { checkForLuaLibType } from "./new";
3837
import { createClassSetup } from "./setup";
3938
import { getExtendedNode, getExtendedType, isStaticNode } from "./utils";
4039

40+
export const transformClassDeclaration: FunctionVisitor<ts.ClassLikeDeclaration> = (declaration, context) => {
41+
// If declaration is a default export, transform to export variable assignment instead
42+
if (hasDefaultExportModifier(declaration)) {
43+
const left = createExportedIdentifier(context, createDefaultExportIdentifier(declaration));
44+
const right = transformClassAsExpression(declaration, context);
45+
return [lua.createAssignmentStatement(left, right, declaration)];
46+
}
47+
48+
const { statements } = transformClassLikeDeclaration(declaration, context);
49+
return statements;
50+
};
51+
52+
export const transformThisExpression: FunctionVisitor<ts.ThisExpression> = node => createSelfIdentifier(node);
53+
4154
export function transformClassAsExpression(
4255
expression: ts.ClassLikeDeclaration,
43-
context: TransformationContext,
44-
isDefaultExport = false
56+
context: TransformationContext
4557
): lua.Expression {
46-
let className: lua.Identifier;
47-
if (expression.name) {
48-
className = transformIdentifier(context, expression.name);
49-
} else if (isDefaultExport) {
50-
className = createDefaultExportIdentifier(expression);
51-
} else {
52-
className = lua.createAnonymousIdentifier();
53-
}
54-
5558
pushScope(context, ScopeType.Function);
56-
const classDeclaration = unwrapVisitorResult(transformClassDeclaration(expression, context, className));
59+
const { statements, name } = transformClassLikeDeclaration(expression, context);
5760
popScope(context);
5861

59-
return createImmediatelyInvokedFunctionExpression(classDeclaration, className, expression);
62+
return createImmediatelyInvokedFunctionExpression(unwrapVisitorResult(statements), name, expression);
6063
}
6164

6265
const classSuperInfos = new WeakMap<TransformationContext, ClassSuperInfo[]>();
@@ -65,28 +68,19 @@ interface ClassSuperInfo {
6568
extendedTypeNode?: ts.ExpressionWithTypeArguments;
6669
}
6770

68-
export function transformClassDeclaration(
71+
function transformClassLikeDeclaration(
6972
classDeclaration: ts.ClassLikeDeclaration,
7073
context: TransformationContext,
7174
nameOverride?: lua.Identifier
72-
): OneToManyVisitorResult<lua.Statement> {
75+
): { statements: lua.Statement[]; name: lua.Identifier } {
7376
let className: lua.Identifier;
74-
let classNameText: string;
7577
if (nameOverride !== undefined) {
7678
className = nameOverride;
77-
classNameText = nameOverride.text;
7879
} else if (classDeclaration.name !== undefined) {
7980
className = transformIdentifier(context, classDeclaration.name);
80-
classNameText = classDeclaration.name.text;
81-
} else if (hasDefaultExportModifier(classDeclaration)) {
82-
const left = createExportedIdentifier(context, createDefaultExportIdentifier(classDeclaration));
83-
const right = transformClassAsExpression(classDeclaration, context, true);
84-
85-
return lua.createAssignmentStatement(left, right, classDeclaration);
8681
} else {
8782
// TypeScript error
8883
className = lua.createAnonymousIdentifier();
89-
classNameText = className.text;
9084
}
9185

9286
const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration));
@@ -196,9 +190,7 @@ export function transformClassDeclaration(
196190
}
197191

198192
if (!isExtension && !isMetaExtension) {
199-
result.push(
200-
...createClassSetup(context, classDeclaration, className, localClassName, classNameText, extendedType)
201-
);
193+
result.push(...createClassSetup(context, classDeclaration, className, localClassName, extendedType));
202194
} else {
203195
for (const f of instanceFields) {
204196
const fieldName = transformPropertyName(context, f.name);
@@ -317,7 +309,7 @@ export function transformClassDeclaration(
317309

318310
superInfo.pop();
319311

320-
return result;
312+
return { statements: result, name: className };
321313
}
322314

323315
export const transformSuperExpression: FunctionVisitor<ts.SuperExpression> = (expression, context) => {
@@ -345,5 +337,3 @@ export const transformSuperExpression: FunctionVisitor<ts.SuperExpression> = (ex
345337

346338
return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype"));
347339
};
348-
349-
export const transformThisExpression: FunctionVisitor<ts.ThisExpression> = node => createSelfIdentifier(node);

src/transformation/visitors/class/setup.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export function createClassSetup(
1717
statement: ts.ClassLikeDeclarationBase,
1818
className: lua.Identifier,
1919
localClassName: lua.Identifier,
20-
classNameText: string,
2120
extendsType?: ts.Type
2221
): lua.Statement[] {
2322
const result: lua.Statement[] = [];
@@ -56,7 +55,7 @@ export function createClassSetup(
5655
result.push(
5756
lua.createAssignmentStatement(
5857
lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("name")),
59-
lua.createStringLiteral(classNameText),
58+
getReflectionClassName(context, statement, className),
6059
statement
6160
)
6261
);
@@ -79,3 +78,23 @@ export function createClassSetup(
7978

8079
return result;
8180
}
81+
82+
export function getReflectionClassName(
83+
context: TransformationContext,
84+
declaration: ts.ClassLikeDeclarationBase,
85+
className: lua.Identifier
86+
): lua.Expression {
87+
if (declaration.name) {
88+
return lua.createStringLiteral(declaration.name.text);
89+
} else if (ts.isVariableDeclaration(declaration.parent) && ts.isIdentifier(declaration.parent.name)) {
90+
return lua.createStringLiteral(declaration.parent.name.text);
91+
} else if (hasDefaultExportModifier(declaration)) {
92+
return lua.createStringLiteral("default");
93+
}
94+
95+
if (getExtendedNode(context, declaration)) {
96+
return lua.createTableIndexExpression(className, lua.createStringLiteral("name"));
97+
}
98+
99+
return lua.createStringLiteral("");
100+
}

test/unit/classes/__snapshots__/classes.spec.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
exports[`missing declaration name: code 1`] = `
44
"require(\\"lualib_bundle\\");
55
____ = __TS__Class()
6-
____.name = \\"____\\"
6+
____.name = \\"\\"
77
function ____.prototype.____constructor(self)
88
end"
99
`;

0 commit comments

Comments
 (0)