From 77adaa1c7d4707157c10baed6c268e643684fed8 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 18 Sep 2021 19:54:15 +0200 Subject: [PATCH 1/9] Sourcemap source files are relative to project root --- src/transpilation/transpile.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index fc645147f..d5fb53507 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -1,9 +1,10 @@ import * as path from "path"; import * as ts from "typescript"; +import { getProjectRoot } from "./transpiler"; import { CompilerOptions, validateOptions } from "../CompilerOptions"; import { createPrinter } from "../LuaPrinter"; import { createVisitorMap, transformSourceFile } from "../transformation"; -import { isNonNull } from "../utils"; +import { isNonNull, normalizeSlashes } from "../utils"; import { getPlugins, Plugin } from "./plugins"; import { getTransformers } from "./transformers"; import { EmitHost, ProcessedFile } from "./utils"; @@ -81,7 +82,8 @@ export function getProgramTranspileResult( console.log(`Printing ${sourceFile.fileName}`); } - const printResult = printer(program, emitHost, sourceFile.fileName, file); + const sourceMapSourceFile = normalizeSlashes(path.relative(getProjectRoot(program), sourceFile.fileName)); + const printResult = printer(program, emitHost, sourceMapSourceFile, file); transpiledFiles.push({ sourceFiles: [sourceFile], fileName: path.normalize(sourceFile.fileName), From 72fef5e1cb1ea9fdea0227af1bd5d0a2a8239229 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 19 Sep 2021 21:10:59 +0200 Subject: [PATCH 2/9] Updated unit test --- src/transpilation/transpile.ts | 4 ++-- test/unit/printer/sourcemaps.spec.ts | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index d5fb53507..a8f70b7ba 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -82,8 +82,8 @@ export function getProgramTranspileResult( console.log(`Printing ${sourceFile.fileName}`); } - const sourceMapSourceFile = normalizeSlashes(path.relative(getProjectRoot(program), sourceFile.fileName)); - const printResult = printer(program, emitHost, sourceMapSourceFile, file); + const relativeSourcePath = normalizeSlashes(path.relative(getProjectRoot(program), sourceFile.fileName)); + const printResult = printer(program, emitHost, relativeSourcePath, file); transpiledFiles.push({ sourceFiles: [sourceFile], fileName: path.normalize(sourceFile.fileName), diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 6c5857120..e8a0cc8a4 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -163,25 +163,33 @@ test.each([ }); test.each([ - { fileName: "/proj/foo.ts", config: {} }, + { + fileName: "/proj/foo.ts", + config: {}, + expectedSourceMapSourcePath: "foo.ts", // Project root inferred as common source directory + }, { fileName: "/proj/src/foo.ts", config: { outDir: "/proj/dst" }, + expectedSourceMapSourcePath: "foo.ts", // Project root inferred as common source directory }, { fileName: "/proj/src/foo.ts", - config: { rootDir: "/proj/src", outDir: "/proj/dst" }, + config: { rootDir: "/proj", outDir: "/proj/dst" }, + expectedSourceMapSourcePath: "src/foo.ts", // rootDir set }, { fileName: "/proj/src/sub/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, + expectedSourceMapSourcePath: "sub/foo.ts", // rootDir set }, { fileName: "/proj/src/sub/main.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" }, - fullSource: "bin/proj/src/sub/main.ts", + fullSource: "bin/sub/main.ts", + expectedSourceMapSourcePath: "sub/main.ts", // rootDir set }, -])("Source map has correct sources (%p)", async ({ fileName, config, fullSource }) => { +])("Source map has correct sources (%p)", async ({ fileName, config, fullSource, expectedSourceMapSourcePath }) => { const file = util.testModule` const foo = "foo" ` @@ -191,11 +199,11 @@ test.each([ const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sources).toHaveLength(1); - expect(sourceMap.sources[0]).toBe(fileName); + expect(sourceMap.sources[0]).toBe(expectedSourceMapSourcePath); const consumer = await new SourceMapConsumer(file.luaSourceMap); expect(consumer.sources).toHaveLength(1); - expect(consumer.sources[0]).toBe(fullSource ?? fileName); + expect(consumer.sources[0]).toBe(fullSource ?? expectedSourceMapSourcePath); }); test.each([ From e1c98789a6451d16b92e6de8530332dd253c7a5a Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 26 Sep 2021 20:41:38 +0200 Subject: [PATCH 3/9] use getEmitPathRelativeToOutDir --- src/LuaPrinter.ts | 9 ++++----- src/transpilation/transpile.ts | 6 ++---- test/unit/printer/sourcemaps.spec.ts | 20 ++++++-------------- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 65c33b88a..cf0ef3d15 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,11 +1,12 @@ import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; +import { getEmitPathRelativeToOutDir } from "."; import * as ts from "typescript"; import { CompilerOptions, isBundleEnabled, LuaLibImportKind } from "./CompilerOptions"; 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, normalizeSlashes } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -120,14 +121,12 @@ export class LuaPrinter { }; private currentIndent = ""; - private sourceFile: string; private options: CompilerOptions; public static readonly sourceMapTracebackPlaceholder = "{#SourceMapTraceback}"; - constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { + constructor(private emitHost: EmitHost, private program: ts.Program, private sourceFile: string) { this.options = program.getCompilerOptions(); - this.sourceFile = fileName; } public print(file: lua.File): PrintResult { @@ -787,7 +786,7 @@ export class LuaPrinter { // will not generate 'empty' mappings in the source map that point to nothing in the original TS. private buildSourceMap(sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator { const map = new SourceMapGenerator({ - file: trimExtension(this.sourceFile) + ".lua", + file: normalizeSlashes(getEmitPathRelativeToOutDir(this.sourceFile, this.program)), sourceRoot, }); diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index a8f70b7ba..fc645147f 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -1,10 +1,9 @@ import * as path from "path"; import * as ts from "typescript"; -import { getProjectRoot } from "./transpiler"; import { CompilerOptions, validateOptions } from "../CompilerOptions"; import { createPrinter } from "../LuaPrinter"; import { createVisitorMap, transformSourceFile } from "../transformation"; -import { isNonNull, normalizeSlashes } from "../utils"; +import { isNonNull } from "../utils"; import { getPlugins, Plugin } from "./plugins"; import { getTransformers } from "./transformers"; import { EmitHost, ProcessedFile } from "./utils"; @@ -82,8 +81,7 @@ export function getProgramTranspileResult( console.log(`Printing ${sourceFile.fileName}`); } - const relativeSourcePath = normalizeSlashes(path.relative(getProjectRoot(program), sourceFile.fileName)); - const printResult = printer(program, emitHost, relativeSourcePath, file); + const printResult = printer(program, emitHost, sourceFile.fileName, file); transpiledFiles.push({ sourceFiles: [sourceFile], fileName: path.normalize(sourceFile.fileName), diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index e8a0cc8a4..6c5857120 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -163,33 +163,25 @@ test.each([ }); test.each([ - { - fileName: "/proj/foo.ts", - config: {}, - expectedSourceMapSourcePath: "foo.ts", // Project root inferred as common source directory - }, + { fileName: "/proj/foo.ts", config: {} }, { fileName: "/proj/src/foo.ts", config: { outDir: "/proj/dst" }, - expectedSourceMapSourcePath: "foo.ts", // Project root inferred as common source directory }, { fileName: "/proj/src/foo.ts", - config: { rootDir: "/proj", outDir: "/proj/dst" }, - expectedSourceMapSourcePath: "src/foo.ts", // rootDir set + config: { rootDir: "/proj/src", outDir: "/proj/dst" }, }, { fileName: "/proj/src/sub/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, - expectedSourceMapSourcePath: "sub/foo.ts", // rootDir set }, { fileName: "/proj/src/sub/main.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" }, - fullSource: "bin/sub/main.ts", - expectedSourceMapSourcePath: "sub/main.ts", // rootDir set + fullSource: "bin/proj/src/sub/main.ts", }, -])("Source map has correct sources (%p)", async ({ fileName, config, fullSource, expectedSourceMapSourcePath }) => { +])("Source map has correct sources (%p)", async ({ fileName, config, fullSource }) => { const file = util.testModule` const foo = "foo" ` @@ -199,11 +191,11 @@ test.each([ const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sources).toHaveLength(1); - expect(sourceMap.sources[0]).toBe(expectedSourceMapSourcePath); + expect(sourceMap.sources[0]).toBe(fileName); const consumer = await new SourceMapConsumer(file.luaSourceMap); expect(consumer.sources).toHaveLength(1); - expect(consumer.sources[0]).toBe(fullSource ?? expectedSourceMapSourcePath); + expect(consumer.sources[0]).toBe(fullSource ?? fileName); }); test.each([ From d71c52e4a3ddc0d39a511140f58445d0924c2744 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 26 Sep 2021 20:42:29 +0200 Subject: [PATCH 4/9] Updated unclear require diagnostic --- src/transpilation/diagnostics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 098d78740..0aa772cd3 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -8,7 +8,7 @@ const createDiagnosticFactory = ( export const couldNotResolveRequire = createDiagnosticFactory( (requirePath: string, containingFile: string) => - `Could not resolve require path '${requirePath}' in file ${containingFile}.` + `Could not resolve lua source files for require path '${requirePath}' in file ${containingFile}.` ); export const couldNotReadDependency = createDiagnosticFactory( From 5e3a67ed34d1a946a22f6ee82ae6e80d134e7d79 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 26 Sep 2021 20:50:01 +0200 Subject: [PATCH 5/9] updated diagnostic snapshot --- test/unit/modules/__snapshots__/resolution.spec.ts.snap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/modules/__snapshots__/resolution.spec.ts.snap b/test/unit/modules/__snapshots__/resolution.spec.ts.snap index 4db74c57f..a250dbd46 100644 --- a/test/unit/modules/__snapshots__/resolution.spec.ts.snap +++ b/test/unit/modules/__snapshots__/resolution.spec.ts.snap @@ -7,4 +7,4 @@ local ____ = module return ____exports" `; -exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"error TSTL: Could not resolve require path '../module' in file main.ts."`; +exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"error TSTL: Could not resolve lua source files for require path '../module' in file main.ts."`; From 2183c244d632c8ec705ba689e203b78caf261072 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 26 Sep 2021 21:58:33 +0200 Subject: [PATCH 6/9] Change sourcenode paths to relative --- src/LuaPrinter.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index cf0ef3d15..9053833fa 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -7,6 +7,7 @@ import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; import { intersperse, normalizeSlashes } from "./utils"; +import path = require("path"); // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -121,12 +122,17 @@ export class LuaPrinter { }; private currentIndent = ""; + private luaFile: string; + private relativeSourcePath: string; private options: CompilerOptions; public static readonly sourceMapTracebackPlaceholder = "{#SourceMapTraceback}"; constructor(private emitHost: EmitHost, private program: ts.Program, private sourceFile: string) { this.options = program.getCompilerOptions(); + this.luaFile = normalizeSlashes(getEmitPathRelativeToOutDir(this.sourceFile, this.program)); + console.log(this.sourceFile, this.luaFile); + this.relativeSourcePath = normalizeSlashes(path.relative(this.luaFile, this.sourceFile)); } public print(file: lua.File): PrintResult { @@ -229,12 +235,12 @@ export class LuaPrinter { const { line, column } = lua.getOriginalPos(node); return line !== undefined && column !== undefined - ? new SourceNode(line + 1, column, this.sourceFile, chunks, name) - : new SourceNode(null, null, this.sourceFile, chunks, name); + ? new SourceNode(line + 1, column, this.relativeSourcePath, chunks, name) + : new SourceNode(null, null, this.relativeSourcePath, chunks, name); } protected concatNodes(...chunks: SourceChunk[]): SourceNode { - return new SourceNode(null, null, this.sourceFile, chunks); + return new SourceNode(null, null, this.relativeSourcePath, chunks); } protected printBlock(block: lua.Block): SourceNode { @@ -756,7 +762,7 @@ export class LuaPrinter { } public printOperator(kind: lua.Operator): SourceNode { - return new SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]); + return new SourceNode(null, null, this.relativeSourcePath, LuaPrinter.operatorMap[kind]); } protected joinChunksWithComma(chunks: SourceChunk[]): SourceChunk[] { @@ -786,7 +792,7 @@ export class LuaPrinter { // will not generate 'empty' mappings in the source map that point to nothing in the original TS. private buildSourceMap(sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator { const map = new SourceMapGenerator({ - file: normalizeSlashes(getEmitPathRelativeToOutDir(this.sourceFile, this.program)), + file: this.luaFile, sourceRoot, }); From 4f0d34c280ee76897c6eeb5f2f5b7941587a191d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 26 Sep 2021 22:30:12 +0200 Subject: [PATCH 7/9] fixed once and for all (hopefully) --- src/LuaPrinter.ts | 8 ++++---- test/unit/printer/sourcemaps.spec.ts | 24 +++++++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 9053833fa..0eb3e1aae 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,5 +1,5 @@ import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; -import { getEmitPathRelativeToOutDir } from "."; +import { getEmitPath } from "."; import * as ts from "typescript"; import { CompilerOptions, isBundleEnabled, LuaLibImportKind } from "./CompilerOptions"; import * as lua from "./LuaAST"; @@ -130,9 +130,9 @@ export class LuaPrinter { constructor(private emitHost: EmitHost, private program: ts.Program, private sourceFile: string) { this.options = program.getCompilerOptions(); - this.luaFile = normalizeSlashes(getEmitPathRelativeToOutDir(this.sourceFile, this.program)); - console.log(this.sourceFile, this.luaFile); - this.relativeSourcePath = normalizeSlashes(path.relative(this.luaFile, this.sourceFile)); + this.luaFile = normalizeSlashes(getEmitPath(this.sourceFile, this.program)); + // Source nodes contain relative path from mapped lua file to original TS source file + this.relativeSourcePath = normalizeSlashes(path.relative(path.dirname(this.luaFile), this.sourceFile)); } public print(file: lua.File): PrintResult { diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 6c5857120..fdc21a13a 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -163,25 +163,35 @@ test.each([ }); test.each([ - { fileName: "/proj/foo.ts", config: {} }, + { + fileName: "/proj/foo.ts", + config: {}, + expectedSourcePath: "foo.ts", // ts and lua will be emitted to same directory + }, { fileName: "/proj/src/foo.ts", - config: { outDir: "/proj/dst" }, + config: { + outDir: "/proj/dst", + }, + expectedSourcePath: "../src/foo.ts", // path from proj/dst outDir to proj/src/foo.ts }, { fileName: "/proj/src/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, + expectedSourcePath: "../src/foo.ts", // path from proj/dst outDir to proj/src/foo.ts }, { fileName: "/proj/src/sub/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, + expectedSourcePath: "../../src/sub/foo.ts", // path from proj/dst/sub outDir to proj/src/sub/foo.ts }, { fileName: "/proj/src/sub/main.ts", - config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" }, - fullSource: "bin/proj/src/sub/main.ts", + config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin/binsub/binsubsub" }, + expectedSourcePath: "../../src/sub/main.ts", // path from proj/dst/sub outDir to proj/src/sub/foo.ts + fullSource: "bin/src/sub/main.ts", }, -])("Source map has correct sources (%p)", async ({ fileName, config, fullSource }) => { +])("Source map has correct sources (%p)", async ({ fileName, config, fullSource, expectedSourcePath }) => { const file = util.testModule` const foo = "foo" ` @@ -191,11 +201,11 @@ test.each([ const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sources).toHaveLength(1); - expect(sourceMap.sources[0]).toBe(fileName); + expect(sourceMap.sources[0]).toBe(expectedSourcePath); const consumer = await new SourceMapConsumer(file.luaSourceMap); expect(consumer.sources).toHaveLength(1); - expect(consumer.sources[0]).toBe(fullSource ?? fileName); + expect(consumer.sources[0]).toBe(fullSource ?? expectedSourcePath); }); test.each([ From e4411d841eb8d22b6498bd54d1c794e6a95474ae Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 26 Sep 2021 22:37:23 +0200 Subject: [PATCH 8/9] fix weird auto-import --- src/LuaPrinter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 0eb3e1aae..2af903ce0 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,3 +1,4 @@ +import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import { getEmitPath } from "."; import * as ts from "typescript"; @@ -7,7 +8,6 @@ import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; import { intersperse, normalizeSlashes } from "./utils"; -import path = require("path"); // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 From e47f05ecc8f2b95765b8a4dc7e9f0dd3c57a7a94 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 26 Sep 2021 22:40:25 +0200 Subject: [PATCH 9/9] Make sourcemap file property only the file name, not the entire path --- src/LuaPrinter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 2af903ce0..4bfe53f5c 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -792,7 +792,7 @@ export class LuaPrinter { // will not generate 'empty' mappings in the source map that point to nothing in the original TS. private buildSourceMap(sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator { const map = new SourceMapGenerator({ - file: this.luaFile, + file: path.basename(this.luaFile), sourceRoot, });