8000 Correctly handle custom extensions during module resolution (#1400) · TypeScriptToLua/TypeScriptToLua@589baeb · GitHub
[go: up one dir, main page]

Skip to content

Commit 589baeb

Browse files
authored
Correctly handle custom extensions during module resolution (#1400)
* Correctly handle custom extensions during module resolution * Fix tests
1 parent 207cabe commit 589baeb

File tree

4 files changed

+46
-17
lines changed

4 files changed

+46
-17
lines changed

src/transpilation/output-collector.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export interface TranspiledFile {
1414
jsSourceMap?: string;
1515
}
1616

17-
export function createEmitOutputCollector() {
17+
export function createEmitOutputCollector(luaExtension = ".lua") {
1818
const files: TranspiledFile[] = [];
1919
const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => {
2020
let file = files.find(f => intersection(f.sourceFiles, sourceFiles).length > 0);
@@ -25,9 +25,9 @@ export function createEmitOutputCollector() {
2525
file.sourceFiles = union(file.sourceFiles, sourceFiles);
2626
}
2727

28-
if (fileName.endsWith(".lua")) {
28+
if (fileName.endsWith(luaExtension)) {
2929
file.lua = data;
30-
} else if (fileName.endsWith(".lua.map")) {
30+
} else if (fileName.endsWith(`${luaExtension}.map`)) {
3131
file.luaSourceMap = data;
3232
} else if (fileName.endsWith(".js")) {
3333
file.js = data;

src/transpilation/resolve.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class ResolutionContext {
4949
// Remove @NoResolution prefix if not building in library mode
5050
if (!isBuildModeLibrary(this.program)) {
5151
const path = required.requirePath.replace("@NoResolution:", "");
52-
replaceRequireInCode(file, required, path);
53-
replaceRequireInSourceMap(file, required, path);
52+
replaceRequireInCode(file, required, path, this.options.extension);
53+
replaceRequireInSourceMap(file, required, path, this.options.extension);
5454
}
5555

5656
// Skip
@@ -88,8 +88,8 @@ class ResolutionContext {
8888
// Figure out resolved require path and dependency output path
8989
if (shouldRewriteRequires(dependencyPath, this.program)) {
9090
const resolvedRequire = getEmitPathRelativeToOutDir(dependencyPath, this.program);
91-
replaceRequireInCode(file, required, resolvedRequire);
92-
replaceRequireInSourceMap(file, required, resolvedRequire);
91+
replaceRequireInCode(file, required, resolvedRequire, this.options.extension);
92+
replaceRequireInSourceMap(file, required, resolvedRequire, this.options.extension);
9393
}
9494
}
9595

@@ -117,8 +117,8 @@ class ResolutionContext {
117117

118118
private couldNotResolveImport(required: LuaRequire, file: ProcessedFile): void {
119119
const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName));
120-
replaceRequireInCode(file, required, fallbackRequire);
121-
replaceRequireInSourceMap(file, required, fallbackRequire);
120+
replaceRequireInCode(file, required, fallbackRequire, this.options.extension);
121+
replaceRequireInSourceMap(file, required, fallbackRequire, this.options.extension);
122122

123123
this.diagnostics.push(
124124
couldNotResolveRequire(required.requirePath, path.relative(getProjectRoot(this.program), file.fileName))
@@ -310,16 +310,26 @@ function isBuildModeLibrary(program: ts.Program) {
310310
return program.getCompilerOptions().buildMode === BuildMode.Library;
311311
}
312312

313-
function replaceRequireInCode(file: ProcessedFile, originalRequire: LuaRequire, newRequire: string): void {
314-
const requirePath = formatPathToLuaPath(newRequire.replace(".lua", ""));
313+
function replaceRequireInCode(
314+
file: ProcessedFile,
315+
originalRequire: LuaRequire,
316+
newRequire: string,
317+
extension: string | undefined
318+
): void {
319+
const requirePath = requirePathForFile(newRequire, extension);
315320
file.code = file.code =
316321
file.code.substring(0, originalRequire.from) +
317322
`require("${requirePath}")` +
318323
file.code.substring(originalRequire.to + 1);
319324
}
320325

321-
function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: LuaRequire, newRequire: string): void {
322-
const requirePath = formatPathToLuaPath(newRequire.replace(".lua", ""));
326+
function replaceRequireInSourceMap(
327+
file: ProcessedFile,
328+
originalRequire: LuaRequire,
329+
newRequire: string,
330+
extension?: string | undefined
331+
): void {
332+
const requirePath = requirePathForFile(newRequire, extension);
323333
if (file.sourceMapNode) {
324334
replaceInSourceMap(
325335
file.sourceMapNode,
@@ -330,6 +340,14 @@ function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: LuaRequ
330340
}
331341
}
332342

343+
function requirePathForFile(filePath: string, extension = ".lua"): string {
344+
if (filePath.endsWith(extension)) {
345+
return formatPathToLuaPath(filePath.substring(0, filePath.length - extension.length));
346+
} else {
347+
return formatPathToLuaPath(filePath);
348+
}
349+
}
350+
333351
function replaceInSourceMap(node: SourceNode, parent: SourceNode, require: string, resolvedRequire: string): boolean {
334352
if ((!node.children || node.children.length === 0) && node.toString() === require) {
335353
parent.children = [new SourceNode(node.line, node.column, node.source, [resolvedRequire])];

test/transpile/module-resolution.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ describe("module resolution with sourceDir", () => {
174174
.setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile })
175175
.expectToEqual(expectedResult);
176176
});
177+
178+
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1394
179+
test("can resolve files with non-standard extension (#1394)", () => {
180+
util.testProject(path.join(projectPath, "tsconfig.json"))
181+
.setMainFileName(path.join(projectPath, "src", "main.ts"))
182+
.setOptions({ outDir: "tstl-out", extension: ".script" })
183+
.expectToEqual(expectedResult);
184+
});
177185
});
178186

179187
describe("module resolution project with lua sources", () => {

test/util.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ export abstract class TestBuilder {
236236
public getLuaResult(): tstl.TranspileVirtualProjectResult {
237237
const program = this.getProgram();
238238
const preEmitDiagnostics = ts.getPreEmitDiagnostics(program);
239-
const collector = createEmitOutputCollector();
239+
const collector = createEmitOutputCollector(this.options.extension);
240240
const { diagnostics: transpileDiagnostics } = new tstl.Transpiler({ emitHost: this.getEmitHost() }).emit({
241241
program,
242242
customTransformers: this.customTransformers,
@@ -277,7 +277,7 @@ export abstract class TestBuilder {
277277
const program = this.getProgram();
278278
program.getCompilerOptions().module = ts.ModuleKind.CommonJS;
279279

280-
const collector = createEmitOutputCollector();
280+
const collector = createEmitOutputCollector(this.options.extension);
281281
const { diagnostics } = program.emit(undefined, collector.writeFile);
282282
return { transpiledFiles: collector.files, diagnostics: [...diagnostics] };
283283
}
@@ -468,7 +468,10 @@ end)());`;
468468
}
469469

470470
private injectLuaFile(state: LuaState, lua: Lua, lauxlib: LauxLib, fileName: string, fileContent: string) {
471-
const modName = formatPathToLuaPath(fileName.replace(".lua", ""));
471+
const extension = this.options.extension ?? ".lua";
472+
const modName = fileName.endsWith(extension)
473+
? formatPathToLuaPath(fileName.substring(0, fileName.length - extension.length))
474+
: fileName;
472475
if (this.options.luaTarget === tstl.LuaTarget.Lua50) {
473476
// Adding source Lua to the _LOADED cache will allow require to find it
474477
lua.lua_getglobal(state, "_LOADED");
@@ -610,7 +613,7 @@ class ProjectTestBuilder extends ModuleTestBuilder {
610613
@memoize
611614
public getLuaResult(): tstl.TranspileVirtualProjectResult {
612615
// Override getLuaResult to use transpileProject with tsconfig.json instead
613-
const collector = createEmitOutputCollector();
616+
const collector = createEmitOutputCollector(this.options.extension);
614617
const { diagnostics } = transpileProject(this.tsConfig, this.options, collector.writeFile);
615618

616619
return { diagnostics: [...diagnostics], transpiledFiles: collector.files };

0 commit comments

Comments
 (0)
0