Skip to content

Commit d5f644c

Browse files
authored
More source map stuff (#633)
* source-mapping function 'end' * support for name mapping in sourcemaps * mapping class new and generated constuctors to declaration * clarification comment for constructor original node * clarifying generated constructor check better
1 parent bccecc5 commit d5f644c

File tree

4 files changed

+93
-22
lines changed

4 files changed

+93
-22
lines changed

src/LuaAST.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,7 @@ export function createMethodCallExpression(
830830
export interface Identifier extends Expression {
831831
kind: SyntaxKind.Identifier;
832832
text: string;
833+
originalName?: string;
833834
symbolId?: SymbolId;
834835
}
835836

@@ -841,16 +842,18 @@ export function createIdentifier(
841842
text: string | ts.__String,
842843
tsOriginal?: ts.Node,
843844
symbolId?: SymbolId,
845+
originalName?: string,
844846
parent?: Node
845847
): Identifier {
846848
const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier;
847849
expression.text = text as string;
848850
expression.symbolId = symbolId;
851+
expression.originalName = originalName;
849852
return expression;
850853
}
851854

852855
export function cloneIdentifier(identifier: Identifier, tsOriginal?: ts.Node): Identifier {
853-
return createIdentifier(identifier.text, tsOriginal, identifier.symbolId);
856+
return createIdentifier(identifier.text, tsOriginal, identifier.symbolId, identifier.originalName);
854857
}
855858

856859
export function createAnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier {

src/LuaPrinter.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,12 @@ export class LuaPrinter {
157157
return this.concatNodes(this.currentIndent, input);
158158
}
159159

160-
protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode {
160+
protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[], name?: string): SourceNode {
161161
const originalPos = tstl.getOriginalPos(node);
162162

163163
return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined
164-
? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks)
165-
: new SourceNode(null, null, this.sourceFile, chunks); // tslint:disable-line:no-null-keyword
164+
? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks, name)
165+
: new SourceNode(null, null, this.sourceFile, chunks, name); // tslint:disable-line:no-null-keyword
166166
}
167167

168168
protected concatNodes(...chunks: SourceChunk[]): SourceNode {
@@ -274,7 +274,7 @@ export class LuaPrinter {
274274
}
275275
}
276276

277-
return this.concatNodes(...chunks);
277+
return this.createSourceNode(statement, chunks);
278278
}
279279

280280
public printVariableAssignmentStatement(statement: tstl.AssignmentStatement): SourceNode {
@@ -516,13 +516,13 @@ export class LuaPrinter {
516516
...this.joinChunks(", ", returnStatement.expressions.map(e => this.printExpression(e))),
517517
];
518518
chunks.push(this.createSourceNode(returnStatement, returnNode));
519-
chunks.push(" end");
519+
chunks.push(this.createSourceNode(expression, " end"));
520520
} else {
521521
chunks.push("\n");
522522
this.pushIndent();
523523
chunks.push(this.printBlock(expression.body));
524524
this.popIndent();
525-
chunks.push(this.indent("end"));
525+
chunks.push(this.indent(this.createSourceNode(expression, "end")));
526526
}
527527

528528
return this.createSourceNode(expression, chunks);
@@ -541,7 +541,7 @@ export class LuaPrinter {
541541
this.pushIndent();
542542
chunks.push(this.printBlock(expression.body));
543543
this.popIndent();
544-
chunks.push(this.indent("end"));
544+
chunks.push(this.indent(this.createSourceNode(statement, "end")));
545545

546546
return this.createSourceNode(expression, chunks);
547547
}
@@ -661,7 +661,11 @@ export class LuaPrinter {
661661
}
662662

663663
public printIdentifier(expression: tstl.Identifier): SourceNode {
664-
return this.createSourceNode(expression, expression.text);
664+
return this.createSourceNode(
665+
expression,
666+
expression.text,
667+
expression.originalName !== expression.text ? expression.originalName : undefined
668+
);
665669
}
666670

667671
public printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode {
@@ -734,12 +738,15 @@ export class LuaPrinter {
734738
}
735739
if (
736740
currentMapping.generated.line === generatedLine &&
737-
currentMapping.generated.column === generatedColumn
741+
currentMapping.generated.column === generatedColumn &&
742+
currentMapping.name === sourceNode.name
738743
) {
739744
return false;
740745
}
741746
return (
742-
currentMapping.original.line !== sourceNode.line || currentMapping.original.column !== sourceNode.column
747+
currentMapping.original.line !== sourceNode.line ||
748+
currentMapping.original.column !== sourceNode.column ||
749+
currentMapping.name !== sourceNode.name
743750
);
744751
};
745752

@@ -749,6 +756,7 @@ export class LuaPrinter {
749756
source: sourceNode.source,
750757
original: { line: sourceNode.line, column: sourceNode.column },
751758
generated: { line: generatedLine, column: generatedColumn },
759+
name: sourceNode.name,
752760
};
753761
map.addMapping(currentMapping);
754762
}

src/LuaTransformer.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,12 @@ export class LuaTransformer {
631631

632632
let localClassName: tstl.Identifier;
633633
if (this.isUnsafeName(className.text)) {
634-
localClassName = tstl.createIdentifier(this.createSafeName(className.text), undefined, className.symbolId);
634+
localClassName = tstl.createIdentifier(
635+
this.createSafeName(className.text),
636+
undefined,
637+
className.symbolId,
638+
className.text
639+
);
635640
tstl.setNodePosition(localClassName, className);
636641
} else {
637642
localClassName = className;
@@ -1066,20 +1071,22 @@ export class LuaTransformer {
10661071
tstl.createCallExpression(tstl.createIdentifier("setmetatable"), [
10671072
tstl.createTableExpression(),
10681073
createClassPrototype(),
1069-
])
1074+
]),
1075+
statement
10701076
);
10711077
newFuncStatements.push(assignSelf);
10721078

10731079
// self:____constructor(...)
10741080
const callConstructor = tstl.createExpressionStatement(
10751081
tstl.createMethodCallExpression(this.createSelfIdentifier(), tstl.createIdentifier("____constructor"), [
10761082
tstl.createDotsLiteral(),
1077-
])
1083+
]),
1084+
statement
10781085
);
10791086
newFuncStatements.push(callConstructor);
10801087

10811088
// return self
1082-
const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()]);
1089+
const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()], statement);
10831090
newFuncStatements.push(returnSelf);
10841091

10851092
// function localClassName.new(construct, ...) ... end
@@ -1092,7 +1099,8 @@ export class LuaTransformer {
10921099
tstl.createDotsLiteral(),
10931100
undefined,
10941101
tstl.FunctionExpressionFlags.Declaration
1095-
)
1102+
),
1103+
statement
10961104
);
10971105
result.push(newFunc);
10981106

@@ -1134,7 +1142,8 @@ export class LuaTransformer {
11341142
this.createSelfIdentifier(),
11351143
getterName,
11361144
tstl.createNilLiteral(),
1137-
])
1145+
]),
1146+
classDeclaration.members.find(ts.isConstructorDeclaration) || classDeclaration
11381147
);
11391148
statements.push(resetGetter);
11401149
}
@@ -1226,6 +1235,8 @@ export class LuaTransformer {
12261235

12271236
const block: tstl.Block = tstl.createBlock(bodyWithFieldInitializers);
12281237

1238+
const constructorWasGenerated = statement.pos === -1;
1239+
12291240
const result = tstl.createAssignmentStatement(
12301241
this.createConstructorName(className),
12311242
tstl.createFunctionExpression(
@@ -1235,7 +1246,7 @@ export class LuaTransformer {
12351246
restParamName,
12361247
tstl.FunctionExpressionFlags.Declaration
12371248
),
1238-
statement
1249+
constructorWasGenerated ? classDeclaration : statement
12391250
);
12401251

12411252
return result;
@@ -1556,7 +1567,8 @@ export class LuaTransformer {
15561567
return tstl.createIdentifier(
15571568
this.createSafeName(declaration.name.text),
15581569
declaration.name,
1559-
moduleSymbol && this.symbolIds.get(moduleSymbol)
1570+
moduleSymbol && this.symbolIds.get(moduleSymbol),
1571+
declaration.name.text
15601572
);
15611573
}
15621574
return this.transformIdentifier(declaration.name as ts.Identifier);
@@ -4698,7 +4710,7 @@ export class LuaTransformer {
46984710
: this.getIdentifierText(identifier);
46994711

47004712
const symbolId = this.getIdentifierSymbolId(identifier);
4701-
return tstl.createIdentifier(text, identifier, symbolId);
4713+
return tstl.createIdentifier(text, identifier, symbolId, this.getIdentifierText(identifier));
47024714
}
47034715

47044716
protected transformIdentifierExpression(expression: ts.Identifier): tstl.Expression {
@@ -4927,7 +4939,7 @@ export class LuaTransformer {
49274939
}
49284940

49294941
protected createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier {
4930-
return tstl.createIdentifier("self", tsOriginal);
4942+
return tstl.createIdentifier("self", tsOriginal, undefined, "this");
49314943
}
49324944

49334945
protected createExportsIdentifier(): tstl.Identifier {

test/unit/sourcemaps.spec.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ test.each([
3333
{ luaPattern: "function abc(", typeScriptPattern: "function abc() {" },
3434
{ luaPattern: "function def(", typeScriptPattern: "function def() {" },
3535
{ luaPattern: "return abc(", typeScriptPattern: "return abc(" },
36+
{ luaPattern: "end", typeScriptPattern: "function def() {" },
3637
],
3738
},
3839
{
@@ -69,7 +70,11 @@ test.each([
6970
},
7071
{
7172
typeScriptSource: `
72-
class Bar extends Foo {}
73+
class Bar extends Foo {
74+
constructor() {
75+
super();
76+
}
77+
}
7378
`,
7479

7580
assertPatterns: [
@@ -82,8 +87,27 @@ test.each([
8287
{ luaPattern: "Bar.____super = Foo", typeScriptPattern: "Foo {" },
8388
{ luaPattern: "setmetatable(Bar,", typeScriptPattern: "Foo {" },
8489
{ luaPattern: "setmetatable(Bar.prototype,", typeScriptPattern: "Foo {" },
90+
{ luaPattern: "function Bar.new", typeScriptPattern: "class Bar" },
91+
{ luaPattern: "function Bar.prototype.____constructor", typeScriptPattern: "constructor" },
8592
],
8693
},
94+
{
95+
typeScriptSource: `
96+
class Foo {
97+
}
98+
`,
99+
100+
assertPatterns: [{ luaPattern: "function Foo.prototype.____constructor", typeScriptPattern: "class Foo" }],
101+
},
102+
{
103+
typeScriptSource: `
104+
class Foo {
105+
bar = "baz";
106+
}
107+
`,
108+
109+
assertPatterns: [{ luaPattern: "function Foo.prototype.____constructor", typeScriptPattern: "class Foo" }],
110+
},
87111
{
88112
typeScriptSource: `
89113
declare const arr: string[];
@@ -161,6 +185,30 @@ test("Source map has correct source root", async () => {
161185
expect(sourceMap.sourceRoot).toBe(".");
162186
});
163187

188+
test.each([
189+
{ code: `const type = "foobar";`, name: "type" },
190+
{ code: `const and = "foobar";`, name: "and" },
191+
{ code: `const $$$ = "foobar";`, name: "$$$" },
192+
{ code: `const foo = { bar() { console.log(this); } };`, name: "this" },
193+
{ code: `function foo($$$: unknown) {}`, name: "$$$" },
194+
{ code: `class $$$ {}`, name: "$$$" },
195+
{ code: `namespace $$$ { const foo = "bar"; }`, name: "$$$" },
196+
])("Source map has correct name mappings (%p)", async ({ code, name }) => {
197+
const { file } = util.transpileStringResult(code);
198+
199+
if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return;
200+
201+
const consumer = await new SourceMapConsumer(file.sourceMap);
202+
const typescriptPosition = lineAndColumnOf(code, name);
203+
let mappedName: string | undefined;
204+
consumer.eachMapping(mapping => {
205+
if (mapping.originalLine === typescriptPosition.line && mapping.originalColumn === typescriptPosition.column) {
206+
mappedName = mapping.name;
207+
}
208+
});
209+
expect(mappedName).toBe(name);
210+
});
211+
164212
test("sourceMapTraceback saves sourcemap in _G", () => {
165213
// Arrange
166214
const typeScriptSource = `

0 commit comments

Comments
 (0)