ts-budgie
Version:
Converts TypeScript code to Budgie.
102 lines (78 loc) • 3.19 kB
text/typescript
import * as path from "path";
import * as ts from "typescript";
import { fullyNormalizeFilePath } from "./utils";
const createSourceFilesMap = (sourceFiles: ts.SourceFile[] | Map<string, ts.SourceFile>) => {
const map = new Map<string, ts.SourceFile>();
if (sourceFiles instanceof Map) {
for (const [fileName, sourceFile] of Array.from(sourceFiles.entries())) {
map.set(fullyNormalizeFilePath(fileName), sourceFile);
}
} else {
for (const sourceFile of sourceFiles) {
map.set(fullyNormalizeFilePath(sourceFile.fileName), sourceFile);
}
}
return map;
};
export class InMemoryCompilerHost implements ts.CompilerHost {
private readonly sourceFiles: Map<string, ts.SourceFile>;
public constructor(sourceFiles: ts.SourceFile[] | Map<string, ts.SourceFile>) {
this.sourceFiles = createSourceFilesMap(sourceFiles);
}
public getDefaultLibFileName() {
return "";
}
// tslint:disable-next-line:variable-name
public getSourceFile(fileName: string, _languageVersion: ts.ScriptTarget, onError?: (message: string) => void): ts.SourceFile {
const sourceFile = this.sourceFiles.get(fullyNormalizeFilePath(fileName));
if (sourceFile !== undefined) {
return sourceFile;
}
const message = `'${fileName}' not found.`;
if (onError !== undefined) {
onError(message);
}
throw new Error(message);
}
public writeFile() {
/* ... */
}
public getCurrentDirectory() {
return ".";
}
public getCanonicalFileName(fileName: string) {
return fileName;
}
public getNewLine() {
return "\n";
}
public useCaseSensitiveFileNames() {
return true;
}
public readonly fileExists = (fileName: string) => this.sourceFiles.has(fullyNormalizeFilePath(fileName));
public readonly readFile = (fileName: string): string => {
const file = this.sourceFiles.get(fullyNormalizeFilePath(fileName));
if (file === undefined) {
throw new Error(`File not found: '${file}'.`);
}
return file.text;
};
public resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModule[] {
return moduleNames.map((rawModuleName: string) => {
const moduleName = fullyNormalizeFilePath(
rawModuleName[0] === "." ? path.join(path.dirname(containingFile), rawModuleName) : path.normalize(rawModuleName),
);
const resolvedFileName = `${moduleName}.ts`;
if (!this.sourceFiles.has(resolvedFileName)) {
throw new Error(`Could not resolve '${resolvedFileName}' from module name '${rawModuleName}' in '${containingFile}'.`);
}
return {
resolvedFileName,
extension: ts.Extension.Ts,
};
});
}
public getDirectories(): string[] {
throw new Error("getDirectories is unsupported in a stub compiler.");
}
}