Skip to content

Commit 7a4388b

Browse files
authored
Fix noImplicitSelf failing due to file paths (#1289)
* Fix noImplicitSelf not working depending on path separator * Fix test path
1 parent b697e8e commit 7a4388b

File tree

4 files changed

+39
-12
lines changed

4 files changed

+39
-12
lines changed

src/transformation/utils/function-context.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export function getDeclarationContextType(
7979

8080
// When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule.
8181
const options = program.getCompilerOptions() as CompilerOptions;
82-
if (options.noImplicitSelf && program.getRootFileNames().includes(signatureDeclaration.getSourceFile().fileName)) {
82+
if (options.noImplicitSelf && program.getSourceFile(signatureDeclaration.getSourceFile().fileName) !== undefined) {
8383
return ContextType.Void;
8484
}
8585

src/transpilation/index.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as path from "path";
33
import * as ts from "typescript";
44
import { parseConfigFileWithSystem } from "../cli/tsconfig";
55
import { CompilerOptions } from "../CompilerOptions";
6+
import { normalizeSlashes } from "../utils";
67
import { createEmitOutputCollector, TranspiledFile } from "./output-collector";
78
import { EmitResult, Transpiler } from "./transpiler";
89

@@ -44,8 +45,12 @@ const libCache: { [key: string]: ts.SourceFile } = {};
4445

4546
/** @internal */
4647
export function createVirtualProgram(input: Record<string, string>, options: CompilerOptions = {}): ts.Program {
48+
const normalizedFiles: Record<string, string> = {};
49+
for (const [path, file] of Object.entries(input)) {
50+
normalizedFiles[normalizeSlashes(path)] = file;
51+
}
4752
const compilerHost: ts.CompilerHost = {
48-
fileExists: fileName => fileName in input || ts.sys.fileExists(fileName),
53+
fileExists: fileName => fileName in normalizedFiles || ts.sys.fileExists(fileName),
4954
getCanonicalFileName: fileName => fileName,
5055
getCurrentDirectory: () => "",
5156
getDefaultLibFileName: ts.getDefaultLibFileName,
@@ -55,8 +60,8 @@ export function createVirtualProgram(input: Record<string, string>, options: Com
5560
writeFile() {},
5661

5762
getSourceFile(fileName) {
58-
if (fileName in input) {
59-
return ts.createSourceFile(fileName, input[fileName], ts.ScriptTarget.Latest, false);
63+
if (fileName in normalizedFiles) {
64+
return ts.createSourceFile(fileName, normalizedFiles[fileName], ts.ScriptTarget.Latest, false);
6065
}
6166

6267
let filePath: string | undefined;
@@ -80,7 +85,7 @@ export function createVirtualProgram(input: Record<string, string>, options: Com
8085
},
8186
};
8287

83-
return ts.createProgram(Object.keys(input), options, compilerHost);
88+
return ts.createProgram(Object.keys(normalizedFiles), options, compilerHost);
8489
}
8590

8691
export interface TranspileVirtualProjectResult {

test/unit/functions/noImplicitSelfOption.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,40 @@
1+
import * as path from "path";
2+
import { transpileFiles } from "../../../src";
13
import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics";
24
import * as util from "../../util";
35

46
test("enables noSelfInFile behavior for functions", () => {
57
util.testFunction`
68
function fooBar() {}
79
const test: (this: void) => void = fooBar;
10+
fooBar();
811
`
912
.setOptions({ noImplicitSelf: true })
1013
.expectToHaveNoDiagnostics();
1114
});
1215

16+
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1084
17+
test.each(["\\", "/"])("transpileFiles handles paths with noImplicitSelf and %s separator (#1084)", separator => {
18+
const projectDir = `${path.dirname(path.dirname(__dirname))}${separator}transpile${separator}project`;
19+
const emittedFiles: Record<string, string> = {};
20+
const { diagnostics } = transpileFiles(
21+
[
22+
`${projectDir}${separator}index.ts`,
23+
`${projectDir}${separator}api.d.ts`,
24+
`${projectDir}${separator}otherFile.ts`,
25+
],
26+
{ noImplicitSelf: true },
27+
(fileName, text) => (emittedFiles[fileName] = text)
28+
);
29+
expect(diagnostics).toHaveLength(0);
30+
expect(Object.keys(emittedFiles)).not.toHaveLength(0);
31+
for (const fileContent of Object.values(emittedFiles)) {
32+
expect(fileContent).toContain("getNumber()");
33+
expect(fileContent).not.toContain("getNumber(self)");
34+
expect(fileContent).not.toContain("getNumber(_G)");
35+
}
36+
});
37+
1338
test("enables noSelfInFile behavior for methods", () => {
1439
util.testFunction`
1540
class FooBar {

test/util.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,14 @@ export abstract class TestBuilder {
172172
protected mainFileName = "main.ts";
173173
public setMainFileName(mainFileName: string): this {
174174
expect(this.hasProgram).toBe(false);
175-
this.mainFileName = normalizeSlashes(mainFileName);
175+
this.mainFileName = mainFileName;
176176
return this;
177177
}
178178

179179
protected extraFiles: Record<string, string> = {};
180180
public addExtraFile(fileName: string, code: string): this {
181181
expect(this.hasProgram).toBe(false);
182-
this.extraFiles[fileName] = code;
182+
this.extraFiles[fileName] = normalizeSlashes(code);
183183
return this;
184184
}
185185

@@ -206,10 +206,7 @@ export abstract class TestBuilder {
206206
Object.entries(this.extraFiles).filter(([fileName]) => !fileName.endsWith(".lua"))
207207
);
208208

209-
return tstl.createVirtualProgram(
210-
{ ...nonLuaExtraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() },
211-
this.options
212-
);
209+
return tstl.createVirtualProgram({ ...nonLuaExtraFiles, [this.mainFileName]: this.getTsCode() }, this.options);
213210
}
214211

215212
private getEmitHost(): EmitHost {
@@ -247,7 +244,7 @@ export abstract class TestBuilder {
247244
const mainFile = this.options.luaBundle
248245
? transpiledFiles[0]
249246
: transpiledFiles.find(({ sourceFiles }) =>
250-
sourceFiles.some(f => normalizeSlashes(f.fileName) === this.mainFileName)
247+
sourceFiles.some(f => f.fileName === normalizeSlashes(this.mainFileName))
251248
);
252249

253250
expect(mainFile).toMatchObject({ lua: expect.any(String), luaSourceMap: expect.any(String) });

0 commit comments

Comments
 (0)