X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 25 additions & 9 deletions src/LuaPrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as lua from "./LuaAST";
import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib";
import { isValidLuaIdentifier } from "./transformation/utils/safe-names";
import { EmitHost } from "./transpilation";
import { intersperse, trimExtension } from "./utils";
import { intersperse, trimExtension, normalizeSlashes } from "./utils";

// https://www.lua.org/pil/2.4.html
// https://www.ecma-international.org/ecma-262/10.0/index.html#table-34
Expand Down Expand Up @@ -87,8 +87,7 @@ export interface PrintResult {

export function createPrinter(printers: Printer[]): Printer {
if (printers.length === 0) {
return (program, emitHost, fileName, ...args) =>
new LuaPrinter(program.getCompilerOptions(), emitHost, fileName).print(...args);
return (program, emitHost, fileName, ...args) => new LuaPrinter(emitHost, program, fileName).print(...args);
} else if (printers.length === 1) {
return printers[0];
} else {
Expand Down Expand Up @@ -127,9 +126,26 @@ export class LuaPrinter {

private currentIndent = "";
private sourceFile: string;
private options: CompilerOptions;

public constructor(private options: CompilerOptions, private emitHost: EmitHost, fileName: string) {
this.sourceFile = path.basename(fileName);
public constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) {
this.options = program.getCompilerOptions();

if (this.options.outDir) {
const relativeFileName = path.relative(program.getCommonSourceDirectory(), fileName);
if (this.options.sourceRoot) {
// When sourceRoot is specified, just use relative path inside rootDir
this.sourceFile = relativeFileName;
} else {
// Calculate relative path from rootDir to outDir
const outputPath = path.resolve(this.options.outDir, relativeFileName);
this.sourceFile = path.relative(path.dirname(outputPath), fileName);
}
// We want forward slashes, even in windows
this.sourceFile = normalizeSlashes(this.sourceFile);
} else {
this.sourceFile = path.basename(fileName); // File will be in same dir as source
}
}

public print(block: lua.Block, luaLibFeatures: Set<LuaLibFeature>): PrintResult {
Expand All @@ -138,10 +154,10 @@ export class LuaPrinter {
luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack);
}

const sourceRoot =
this.options.sourceRoot ||
(this.options.outDir ? path.relative(this.options.outDir, this.options.rootDir || process.cwd()) : ".");

const sourceRoot = this.options.sourceRoot
? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included
this.options.sourceRoot.replace(/[\\\/]+$/, "") + "/"
: "";
const rootSourceNode = this.printImplementation(block, luaLibFeatures);
const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode);

Expand Down
2 changes: 1 addition & 1 deletion test/transpile/plugins/printer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as tstl from "../../../src";

const plugin: tstl.Plugin = {
printer: (program, emitHost, fileName, ...args) => {
const result = new tstl.LuaPrinter(program.getCompilerOptions(), emitHost, fileName).print(...args);
const result = new tstl.LuaPrinter(emitHost, program, fileName).print(...args);
result.code = `-- Plugin\n${result.code}`;
return result;
},
Expand Down
47 changes: 42 additions & 5 deletions test/unit/printer/sourcemaps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,27 +159,64 @@ test.each([
}
});

test("Source map has correct sources", async () => {
test.each([
{ fileName: "/proj/foo.ts", config: {}, mapSource: "foo.ts", fullSource: "foo.ts" },
{
fileName: "/proj/src/foo.ts",
config: { outDir: "/proj/dst" },
mapSource: "../src/foo.ts",
fullSource: "../src/foo.ts",
},
{
fileName: "/proj/src/foo.ts",
config: { rootDir: "/proj/src", outDir: "/proj/dst" },
mapSource: "../src/foo.ts",
fullSource: "../src/foo.ts",
},
{
fileName: "/proj/src/sub/foo.ts",
config: { rootDir: "/proj/src", outDir: "/proj/dst" },
mapSource: "../../src/sub/foo.ts",
fullSource: "../../src/sub/foo.ts",
},
{
fileName: "/proj/src/sub/main.ts",
config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" },
mapSource: "sub/main.ts",
fullSource: "bin/sub/main.ts",
},
])("Source map has correct sources (%p)", async ({ fileName, config, mapSource, fullSource }) => {
const file = util.testModule`
const foo = "foo"
`
.expectToHaveNoDiagnostics()
.setOptions(config)
.setMainFileName(fileName)
.getMainLuaFileResult();

const sourceMap = JSON.parse(file.sourceMap);
expect(sourceMap.sources.length).toBe(1);
expect(sourceMap.sources[0]).toBe(mapSource);

const consumer = await new SourceMapConsumer(file.sourceMap);
expect(consumer.sources.length).toBe(1);
expect(consumer.sources[0]).toBe("main.ts");
expect(consumer.sources[0]).toBe(fullSource);
});

test("Source map has correct source root", async () => {
test.each([
{ configSourceRoot: undefined, mapSourceRoot: "" },
{ configSourceRoot: "src", mapSourceRoot: "src/" },
{ configSourceRoot: "src/", mapSourceRoot: "src/" },
{ configSourceRoot: "src\\", mapSourceRoot: "src/" },
])("Source map has correct source root (%p)", async ({ configSourceRoot, mapSourceRoot }) => {
const file = util.testModule`
const foo = "foo"
`
.setOptions({ sourceMap: true, sourceRoot: configSourceRoot })
.expectToHaveNoDiagnostics()
.getMainLuaFileResult();

const sourceMap = JSON.parse(file.sourceMap);
expect(sourceMap.sourceRoot).toBe(".");
expect(sourceMap.sourceRoot).toBe(mapSourceRoot);
});

test.each([
Expand Down
X Tutup