mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-11 01:34:55 -06:00
Cleanup and reorganize fakes
This commit is contained in:
parent
1658770015
commit
0322d71515
@ -5,229 +5,19 @@
|
||||
/// <reference path="./vfs.ts" />
|
||||
/// <reference path="./vfsutils.ts" />
|
||||
/// <reference path="./utils.ts" />
|
||||
/// <reference path="./fakes.ts" />
|
||||
|
||||
// NOTE: The contents of this file are all exported from the namespace 'compiler'. This is to
|
||||
// support the eventual conversion of harness into a modular system.
|
||||
|
||||
namespace compiler {
|
||||
/**
|
||||
* A `ts.CompilerHost` that leverages a virtual file system.
|
||||
*/
|
||||
export class CompilerHost implements ts.CompilerHost {
|
||||
public readonly vfs: vfs.FileSystem;
|
||||
public readonly defaultLibLocation: string;
|
||||
public readonly outputs: documents.TextDocument[] = [];
|
||||
public readonly traces: string[] = [];
|
||||
public readonly shouldAssertInvariants = !Harness.lightMode;
|
||||
|
||||
private _setParentNodes: boolean;
|
||||
private _sourceFiles: core.SortedMap<string, ts.SourceFile>;
|
||||
private _newLine: string;
|
||||
private _parseConfigHost: ParseConfigHost;
|
||||
|
||||
constructor(vfs: vfs.FileSystem, options: ts.CompilerOptions, setParentNodes = false) {
|
||||
this.vfs = vfs;
|
||||
this.defaultLibLocation = vfs.meta.get("defaultLibLocation") || "";
|
||||
this._sourceFiles = new core.SortedMap<string, ts.SourceFile>({ comparer: this.vfs.stringComparer, sort: "insertion" });
|
||||
this._newLine = options.newLine === ts.NewLineKind.LineFeed ? "\n" : "\r\n";
|
||||
this._setParentNodes = setParentNodes;
|
||||
}
|
||||
|
||||
public get parseConfigHost() {
|
||||
return this._parseConfigHost || (this._parseConfigHost = new ParseConfigHost(this.vfs));
|
||||
}
|
||||
|
||||
public getCurrentDirectory(): string {
|
||||
return this.vfs.cwd();
|
||||
}
|
||||
|
||||
public useCaseSensitiveFileNames(): boolean {
|
||||
return !this.vfs.ignoreCase;
|
||||
}
|
||||
|
||||
public getNewLine(): string {
|
||||
return this._newLine;
|
||||
}
|
||||
|
||||
public getCanonicalFileName(fileName: string): string {
|
||||
return this.vfs.ignoreCase ? fileName.toLowerCase() : fileName;
|
||||
}
|
||||
|
||||
public fileExists(fileName: string): boolean {
|
||||
return vfsutils.fileExists(this.vfs, fileName);
|
||||
}
|
||||
|
||||
public directoryExists(directoryName: string): boolean {
|
||||
return vfsutils.directoryExists(this.vfs, directoryName);
|
||||
}
|
||||
|
||||
public getDirectories(path: string): string[] {
|
||||
return vfsutils.getDirectories(this.vfs, path);
|
||||
}
|
||||
|
||||
public readFile(path: string): string | undefined {
|
||||
if (path.endsWith("lib.d.ts")) debugger;
|
||||
return vfsutils.readFile(this.vfs, path);
|
||||
}
|
||||
|
||||
public writeFile(fileName: string, content: string, writeByteOrderMark: boolean) {
|
||||
if (writeByteOrderMark) content = core.addUTF8ByteOrderMark(content);
|
||||
vfsutils.writeFile(this.vfs, fileName, content);
|
||||
const document = new documents.TextDocument(fileName, content);
|
||||
document.meta.set("fileName", fileName);
|
||||
this.vfs.filemeta(fileName).set("document", document);
|
||||
const index = this.outputs.findIndex(output => this.vfs.stringComparer(document.file, output.file) === 0);
|
||||
if (index < 0) {
|
||||
this.outputs.push(document);
|
||||
}
|
||||
else {
|
||||
this.outputs[index] = document;
|
||||
}
|
||||
}
|
||||
|
||||
public trace(s: string): void {
|
||||
this.traces.push(s);
|
||||
}
|
||||
|
||||
public realpath(path: string): string {
|
||||
return this.vfs.realpathSync(path);
|
||||
}
|
||||
|
||||
public getDefaultLibLocation(): string {
|
||||
return vpath.resolve(this.vfs.cwd(), this.defaultLibLocation);
|
||||
}
|
||||
|
||||
public getDefaultLibFileName(options: ts.CompilerOptions): string {
|
||||
// return vpath.resolve(this.getDefaultLibLocation(), ts.getDefaultLibFileName(options));
|
||||
|
||||
// TODO(rbuckton): This patches the baseline to replace lib.es5.d.ts with lib.d.ts.
|
||||
// This is only to make the PR for this change easier to read. A follow-up PR will
|
||||
// revert this change and accept the new baselines.
|
||||
// See https://github.com/Microsoft/TypeScript/pull/20763#issuecomment-352553264
|
||||
return vpath.resolve(this.getDefaultLibLocation(), getDefaultLibFileName(options));
|
||||
function getDefaultLibFileName(options: ts.CompilerOptions) {
|
||||
switch (options.target) {
|
||||
case ts.ScriptTarget.ESNext:
|
||||
case ts.ScriptTarget.ES2017:
|
||||
return "lib.es2017.d.ts";
|
||||
case ts.ScriptTarget.ES2016:
|
||||
return "lib.es2016.d.ts";
|
||||
case ts.ScriptTarget.ES2015:
|
||||
return "lib.es2015.d.ts";
|
||||
|
||||
default:
|
||||
return "lib.d.ts";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getSourceFile(fileName: string, languageVersion: number): ts.SourceFile | undefined {
|
||||
const canonicalFileName = this.getCanonicalFileName(vpath.resolve(this.vfs.cwd(), fileName));
|
||||
const existing = this._sourceFiles.get(canonicalFileName);
|
||||
if (existing) return existing;
|
||||
|
||||
const content = this.readFile(canonicalFileName);
|
||||
if (content === undefined) return undefined;
|
||||
|
||||
// A virtual file system may shadow another existing virtual file system. This
|
||||
// allows us to reuse a common virtual file system structure across multiple
|
||||
// tests. If a virtual file is a shadow, it is likely that the file will be
|
||||
// reused across multiple tests. In that case, we cache the SourceFile we parse
|
||||
// so that it can be reused across multiple tests to avoid the cost of
|
||||
// repeatedly parsing the same file over and over (such as lib.d.ts).
|
||||
const cacheKey = this.vfs.shadowRoot && `SourceFile[languageVersion=${languageVersion},setParentNodes=${this._setParentNodes}]`;
|
||||
if (cacheKey) {
|
||||
const meta = this.vfs.filemeta(canonicalFileName);
|
||||
const sourceFileFromMetadata = meta.get(cacheKey) as ts.SourceFile | undefined;
|
||||
if (sourceFileFromMetadata) {
|
||||
this._sourceFiles.set(canonicalFileName, sourceFileFromMetadata);
|
||||
return sourceFileFromMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
const parsed = ts.createSourceFile(fileName, content, languageVersion, this._setParentNodes || this.shouldAssertInvariants);
|
||||
if (this.shouldAssertInvariants) {
|
||||
Utils.assertInvariants(parsed, /*parent*/ undefined);
|
||||
}
|
||||
|
||||
this._sourceFiles.set(canonicalFileName, parsed);
|
||||
|
||||
if (cacheKey) {
|
||||
// store the cached source file on the unshadowed file with the same version.
|
||||
const stats = this.vfs.statSync(canonicalFileName);
|
||||
|
||||
let fs = this.vfs;
|
||||
while (fs.shadowRoot) {
|
||||
try {
|
||||
const shadowRootStats = fs.shadowRoot.statSync(canonicalFileName);
|
||||
if (shadowRootStats.dev !== stats.dev ||
|
||||
shadowRootStats.ino !== stats.ino ||
|
||||
shadowRootStats.mtimeMs !== stats.mtimeMs) {
|
||||
break;
|
||||
}
|
||||
|
||||
fs = fs.shadowRoot;
|
||||
}
|
||||
catch {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fs !== this.vfs) {
|
||||
fs.filemeta(canonicalFileName).set(cacheKey, parsed);
|
||||
}
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `ts.ParseConfigHost` that leverages a virtual file system.
|
||||
*/
|
||||
export class ParseConfigHost implements ts.ParseConfigHost {
|
||||
public readonly vfs: vfs.FileSystem;
|
||||
|
||||
constructor(vfs: vfs.FileSystem) {
|
||||
this.vfs = vfs;
|
||||
}
|
||||
|
||||
public get useCaseSensitiveFileNames() {
|
||||
return !this.vfs.ignoreCase;
|
||||
}
|
||||
|
||||
public fileExists(fileName: string): boolean {
|
||||
return vfsutils.fileExists(this.vfs, fileName);
|
||||
}
|
||||
|
||||
public directoryExists(directoryName: string): boolean {
|
||||
return vfsutils.directoryExists(this.vfs, directoryName);
|
||||
}
|
||||
|
||||
public readFile(path: string): string | undefined {
|
||||
return vfsutils.readFile(this.vfs, path);
|
||||
}
|
||||
|
||||
public readDirectory(path: string, extensions: string[], excludes: string[], includes: string[], depth: number): string[] {
|
||||
return ts.matchFiles(
|
||||
path,
|
||||
extensions,
|
||||
excludes,
|
||||
includes,
|
||||
!this.vfs.ignoreCase,
|
||||
this.vfs.cwd(),
|
||||
depth,
|
||||
path => vfsutils.getAccessibleFileSystemEntries(this.vfs, path));
|
||||
}
|
||||
}
|
||||
|
||||
export interface Project {
|
||||
file: string;
|
||||
config?: ts.ParsedCommandLine;
|
||||
errors?: ts.Diagnostic[];
|
||||
}
|
||||
|
||||
export function readProject(host: ParseConfigHost, project: string | undefined, existingOptions?: ts.CompilerOptions): Project | undefined {
|
||||
export function readProject(host: fakes.ParseConfigHost, project: string | undefined, existingOptions?: ts.CompilerOptions): Project | undefined {
|
||||
if (project) {
|
||||
project = host.vfs.stringComparer(vpath.basename(project), "tsconfig.json") === 0 ? project :
|
||||
vpath.combine(project, "tsconfig.json");
|
||||
@ -265,7 +55,7 @@ namespace compiler {
|
||||
}
|
||||
|
||||
export class CompilationResult {
|
||||
public readonly host: CompilerHost;
|
||||
public readonly host: fakes.CompilerHost;
|
||||
public readonly program: ts.Program | undefined;
|
||||
public readonly result: ts.EmitResult | undefined;
|
||||
public readonly options: ts.CompilerOptions;
|
||||
@ -277,7 +67,7 @@ namespace compiler {
|
||||
private _inputs: documents.TextDocument[] = [];
|
||||
private _inputsAndOutputs: core.SortedMap<string, CompilationOutput>;
|
||||
|
||||
constructor(host: CompilerHost, options: ts.CompilerOptions, program: ts.Program | undefined, result: ts.EmitResult | undefined, diagnostics: ts.Diagnostic[]) {
|
||||
constructor(host: fakes.CompilerHost, options: ts.CompilerOptions, program: ts.Program | undefined, result: ts.EmitResult | undefined, diagnostics: ts.Diagnostic[]) {
|
||||
this.host = host;
|
||||
this.program = program;
|
||||
this.result = result;
|
||||
@ -438,7 +228,7 @@ namespace compiler {
|
||||
}
|
||||
}
|
||||
|
||||
export function compileFiles(host: CompilerHost, rootFiles: string[] | undefined, compilerOptions: ts.CompilerOptions): CompilationResult {
|
||||
export function compileFiles(host: fakes.CompilerHost, rootFiles: string[] | undefined, compilerOptions: ts.CompilerOptions): CompilationResult {
|
||||
if (compilerOptions.project || !rootFiles || rootFiles.length === 0) {
|
||||
const project = readProject(host.parseConfigHost, compilerOptions.project, compilerOptions);
|
||||
if (project) {
|
||||
|
||||
@ -15,16 +15,12 @@ namespace core {
|
||||
}
|
||||
|
||||
export function getByteOrderMarkLength(text: string): number {
|
||||
if (text.length >= 2) {
|
||||
if (text.length >= 1) {
|
||||
const ch0 = text.charCodeAt(0);
|
||||
const ch1 = text.charCodeAt(1);
|
||||
if ((ch0 === 0xff && ch1 === 0xfe) ||
|
||||
(ch0 === 0xfe && ch1 === 0xff)) {
|
||||
return 2;
|
||||
}
|
||||
if (text.length >= 3 && ch0 === 0xef && ch1 === 0xbb && text.charCodeAt(2) === 0xbf) {
|
||||
return 3;
|
||||
}
|
||||
if (ch0 === 0xfeff) return 1;
|
||||
if (ch0 === 0xfe) return text.length >= 2 && text.charCodeAt(1) === 0xff ? 2 : 0;
|
||||
if (ch0 === 0xff) return text.length >= 2 && text.charCodeAt(1) === 0xfe ? 2 : 0;
|
||||
if (ch0 === 0xef) return text.length >= 3 && text.charCodeAt(1) === 0xbb && text.charCodeAt(2) === 0xbf ? 3 : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -9,76 +9,63 @@
|
||||
namespace fakes {
|
||||
const processExitSentinel = new Error("System exit");
|
||||
|
||||
export interface ServerHostOptions {
|
||||
/**
|
||||
* The virtual path to tsc.js. If not specified, a default of `"/.ts/tsc.js"` is used.
|
||||
*/
|
||||
export interface SystemOptions {
|
||||
executingFilePath?: string;
|
||||
newLine?: "\r\n" | "\n";
|
||||
safeList?: boolean;
|
||||
lib?: boolean;
|
||||
dos?: boolean;
|
||||
env?: Record<string, string>;
|
||||
}
|
||||
|
||||
export class ServerHost implements ts.server.ServerHost, ts.FormatDiagnosticsHost {
|
||||
/**
|
||||
* A fake `ts.System` that leverages a virtual file system.
|
||||
*/
|
||||
export class System implements ts.System {
|
||||
public readonly vfs: vfs.FileSystem;
|
||||
public readonly args: string[] = [];
|
||||
public readonly output: string[] = [];
|
||||
public readonly newLine: string;
|
||||
public readonly useCaseSensitiveFileNames: boolean;
|
||||
public exitCode: number;
|
||||
private readonly _output: string[] = [];
|
||||
private readonly _executingFilePath: string;
|
||||
private readonly _getCanonicalFileName: (file: string) => string;
|
||||
|
||||
constructor(vfs: vfs.FileSystem, options: ServerHostOptions = {}) {
|
||||
const {
|
||||
dos = false,
|
||||
executingFilePath = dos
|
||||
? vfsutils.dosTscPath
|
||||
: vfsutils.tscPath,
|
||||
newLine = "\n",
|
||||
safeList = false,
|
||||
lib = false,
|
||||
} = options;
|
||||
private readonly _executingFilePath: string | undefined;
|
||||
private readonly _env: Record<string, string> | undefined;
|
||||
|
||||
constructor(vfs: vfs.FileSystem, { executingFilePath, newLine = "\n", env }: SystemOptions = {}) {
|
||||
this.vfs = vfs.isReadonly ? vfs.shadow() : vfs;
|
||||
this.useCaseSensitiveFileNames = !this.vfs.ignoreCase;
|
||||
this.newLine = newLine;
|
||||
this._executingFilePath = executingFilePath;
|
||||
this._getCanonicalFileName = ts.createGetCanonicalFileName(this.useCaseSensitiveFileNames);
|
||||
|
||||
if (safeList) {
|
||||
const safelistPath = dos ? vfsutils.dosSafelistPath : vfsutils.safelistPath;
|
||||
this.vfs.mkdirpSync(vpath.dirname(safelistPath));
|
||||
this.vfs.writeFileSync(safelistPath, vfsutils.safelistContent);
|
||||
}
|
||||
|
||||
if (lib) {
|
||||
const libPath = dos ? vfsutils.dosLibPath : vfsutils.libPath;
|
||||
this.vfs.mkdirpSync(vpath.dirname(libPath));
|
||||
this.vfs.writeFileSync(libPath, vfsutils.emptyLibContent);
|
||||
}
|
||||
this._env = env;
|
||||
}
|
||||
|
||||
// #region System members
|
||||
public readonly newLine: string;
|
||||
public readonly useCaseSensitiveFileNames: boolean;
|
||||
|
||||
public write(message: string) {
|
||||
this._output.push(message);
|
||||
this.output.push(message);
|
||||
}
|
||||
|
||||
public readFile(path: string) {
|
||||
return vfsutils.readFile(this.vfs, path);
|
||||
try {
|
||||
const content = this.vfs.readFileSync(path, "utf8");
|
||||
return content === undefined ? undefined :
|
||||
vpath.extname(path) === ".json" ? utils.removeComments(core.removeByteOrderMark(content), utils.CommentRemoval.leadingAndTrailing) :
|
||||
core.removeByteOrderMark(content);
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
public writeFile(path: string, data: string, writeByteOrderMark?: boolean): void {
|
||||
vfsutils.writeFile(this.vfs, path, data, writeByteOrderMark);
|
||||
this.vfs.mkdirpSync(vpath.dirname(path));
|
||||
this.vfs.writeFileSync(path, writeByteOrderMark ? core.addUTF8ByteOrderMark(data) : data);
|
||||
}
|
||||
|
||||
public fileExists(path: string) {
|
||||
return vfsutils.fileExists(this.vfs, path);
|
||||
const stats = this._getStats(path);
|
||||
return stats ? stats.isFile() : false;
|
||||
}
|
||||
|
||||
public directoryExists(path: string) {
|
||||
return vfsutils.directoryExists(this.vfs, path);
|
||||
const stats = this._getStats(path);
|
||||
return stats ? stats.isDirectory() : false;
|
||||
}
|
||||
|
||||
public createDirectory(path: string): void {
|
||||
@ -90,12 +77,38 @@ namespace fakes {
|
||||
}
|
||||
|
||||
public getDirectories(path: string) {
|
||||
return vfsutils.getDirectories(this.vfs, path);
|
||||
const result: string[] = [];
|
||||
try {
|
||||
for (const file of this.vfs.readdirSync(path)) {
|
||||
if (this.vfs.statSync(vpath.combine(path, file)).isDirectory()) {
|
||||
result.push(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { /*ignore*/ }
|
||||
return result;
|
||||
}
|
||||
|
||||
public readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
|
||||
return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.vfs.cwd(), depth, path => {
|
||||
return vfsutils.getAccessibleFileSystemEntries(this.vfs, path);
|
||||
return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, path => {
|
||||
const files: string[] = [];
|
||||
const directories: string[] = [];
|
||||
try {
|
||||
for (const file of this.vfs.readdirSync(path)) {
|
||||
try {
|
||||
const stats = this.vfs.statSync(vpath.combine(path, file));
|
||||
if (stats.isFile()) {
|
||||
files.push(file);
|
||||
}
|
||||
else if (stats.isDirectory()) {
|
||||
directories.push(file);
|
||||
}
|
||||
}
|
||||
catch { /*ignored*/ }
|
||||
}
|
||||
}
|
||||
catch { /*ignored*/ }
|
||||
return { files, directories };
|
||||
});
|
||||
}
|
||||
|
||||
@ -104,18 +117,9 @@ namespace fakes {
|
||||
throw processExitSentinel;
|
||||
}
|
||||
|
||||
public readonly args: string[] = [];
|
||||
|
||||
public getFileSize(path: string) {
|
||||
return vfsutils.getFileSize(this.vfs, path);
|
||||
}
|
||||
|
||||
public watchFile(_path: string, _cb: ts.FileWatcherCallback): ts.FileWatcher {
|
||||
return { close(): void { /*ignored*/ } };
|
||||
}
|
||||
|
||||
public watchDirectory(_path: string, _cb: ts.DirectoryWatcherCallback, _recursive?: boolean): ts.FileWatcher {
|
||||
return { close(): void { /*ignored*/ } };
|
||||
const stats = this._getStats(path);
|
||||
return stats && stats.isFile() ? stats.size : 0;
|
||||
}
|
||||
|
||||
public resolvePath(path: string) {
|
||||
@ -123,11 +127,13 @@ namespace fakes {
|
||||
}
|
||||
|
||||
public getExecutingFilePath() {
|
||||
if (this._executingFilePath === undefined) return ts.notImplemented();
|
||||
return this._executingFilePath;
|
||||
}
|
||||
|
||||
public getModifiedTime(path: string) {
|
||||
return vfsutils.getModifiedTime(this.vfs, path);
|
||||
const stats = this._getStats(path);
|
||||
return stats ? stats.mtime : undefined;
|
||||
}
|
||||
|
||||
public createHash(data: string): string {
|
||||
@ -143,38 +149,231 @@ namespace fakes {
|
||||
}
|
||||
}
|
||||
|
||||
public getEnvironmentVariable(_name: string): string | undefined {
|
||||
return undefined;
|
||||
public getEnvironmentVariable(name: string): string | undefined {
|
||||
return this._env && this._env[name];
|
||||
}
|
||||
|
||||
public setTimeout(_callback: (...args: any[]) => void, _timeout: number, ..._args: any[]) {
|
||||
return ts.notImplemented();
|
||||
private _getStats(path: string) {
|
||||
try {
|
||||
return this.vfs.statSync(path);
|
||||
}
|
||||
catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A fake `ts.ParseConfigHost` that leverages a virtual file system.
|
||||
*/
|
||||
export class ParseConfigHost implements ts.ParseConfigHost {
|
||||
public readonly sys: System;
|
||||
|
||||
constructor(sys: System | vfs.FileSystem) {
|
||||
if (sys instanceof vfs.FileSystem) sys = new System(sys);
|
||||
this.sys = sys;
|
||||
}
|
||||
|
||||
public clearTimeout(_timeoutId: any): void {
|
||||
return ts.notImplemented();
|
||||
}
|
||||
// #endregion System members
|
||||
|
||||
// #region FormatDiagnosticsHost members
|
||||
public getNewLine() {
|
||||
return this.newLine;
|
||||
public get vfs() {
|
||||
return this.sys.vfs;
|
||||
}
|
||||
|
||||
public getCanonicalFileName(fileName: string) {
|
||||
return this._getCanonicalFileName(fileName);
|
||||
}
|
||||
// #endregion FormatDiagnosticsHost members
|
||||
|
||||
// #region ServerHost members
|
||||
public setImmediate(_callback: (...args: any[]) => void, ..._args: any[]): any {
|
||||
return ts.notImplemented();
|
||||
public get useCaseSensitiveFileNames() {
|
||||
return this.sys.useCaseSensitiveFileNames;
|
||||
}
|
||||
|
||||
public clearImmediate(_timeoutId: any): void {
|
||||
return ts.notImplemented();
|
||||
public fileExists(fileName: string): boolean {
|
||||
return this.sys.fileExists(fileName);
|
||||
}
|
||||
|
||||
public directoryExists(directoryName: string): boolean {
|
||||
return this.sys.directoryExists(directoryName);
|
||||
}
|
||||
|
||||
public readFile(path: string): string | undefined {
|
||||
return this.sys.readFile(path);
|
||||
}
|
||||
|
||||
public readDirectory(path: string, extensions: string[], excludes: string[], includes: string[], depth: number): string[] {
|
||||
return this.sys.readDirectory(path, extensions, excludes, includes, depth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A fake `ts.CompilerHost` that leverages a virtual file system.
|
||||
*/
|
||||
export class CompilerHost implements ts.CompilerHost {
|
||||
public readonly sys: System;
|
||||
public readonly defaultLibLocation: string;
|
||||
public readonly outputs: documents.TextDocument[] = [];
|
||||
public readonly traces: string[] = [];
|
||||
public readonly shouldAssertInvariants = !Harness.lightMode;
|
||||
|
||||
private _setParentNodes: boolean;
|
||||
private _sourceFiles: core.SortedMap<string, ts.SourceFile>;
|
||||
private _parseConfigHost: ParseConfigHost;
|
||||
private _newLine: string;
|
||||
|
||||
constructor(sys: System | vfs.FileSystem, options: ts.CompilerOptions, setParentNodes = false) {
|
||||
if (sys instanceof vfs.FileSystem) sys = new System(sys, { newLine: "\r\n" });
|
||||
this.sys = sys;
|
||||
this.defaultLibLocation = sys.vfs.meta.get("defaultLibLocation") || "";
|
||||
this._newLine = ts.getNewLineCharacter(options, () => this.sys.newLine);
|
||||
this._sourceFiles = new core.SortedMap<string, ts.SourceFile>({ comparer: sys.vfs.stringComparer, sort: "insertion" });
|
||||
this._setParentNodes = setParentNodes;
|
||||
}
|
||||
|
||||
public get vfs() {
|
||||
return this.sys.vfs;
|
||||
}
|
||||
|
||||
public get parseConfigHost() {
|
||||
return this._parseConfigHost || (this._parseConfigHost = new ParseConfigHost(this.sys));
|
||||
}
|
||||
|
||||
public getCurrentDirectory(): string {
|
||||
return this.sys.getCurrentDirectory();
|
||||
}
|
||||
|
||||
public useCaseSensitiveFileNames(): boolean {
|
||||
return this.sys.useCaseSensitiveFileNames;
|
||||
}
|
||||
|
||||
public getNewLine(): string {
|
||||
return this._newLine;
|
||||
}
|
||||
|
||||
public getCanonicalFileName(fileName: string): string {
|
||||
return this.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
|
||||
public fileExists(fileName: string): boolean {
|
||||
return this.sys.fileExists(fileName);
|
||||
}
|
||||
|
||||
public directoryExists(directoryName: string): boolean {
|
||||
return this.sys.directoryExists(directoryName);
|
||||
}
|
||||
|
||||
public getDirectories(path: string): string[] {
|
||||
return this.sys.getDirectories(path);
|
||||
}
|
||||
|
||||
public readFile(path: string): string | undefined {
|
||||
return this.sys.readFile(path);
|
||||
}
|
||||
|
||||
public writeFile(fileName: string, content: string, writeByteOrderMark: boolean) {
|
||||
if (writeByteOrderMark) content = core.addUTF8ByteOrderMark(content);
|
||||
this.sys.writeFile(fileName, content);
|
||||
|
||||
const document = new documents.TextDocument(fileName, content);
|
||||
document.meta.set("fileName", fileName);
|
||||
this.vfs.filemeta(fileName).set("document", document);
|
||||
const index = this.outputs.findIndex(output => this.vfs.stringComparer(document.file, output.file) === 0);
|
||||
if (index < 0) {
|
||||
this.outputs.push(document);
|
||||
}
|
||||
else {
|
||||
this.outputs[index] = document;
|
||||
}
|
||||
}
|
||||
|
||||
public trace(s: string): void {
|
||||
this.traces.push(s);
|
||||
}
|
||||
|
||||
public realpath(path: string): string {
|
||||
return this.sys.realpath(path);
|
||||
}
|
||||
|
||||
public getDefaultLibLocation(): string {
|
||||
return vpath.resolve(this.getCurrentDirectory(), this.defaultLibLocation);
|
||||
}
|
||||
|
||||
public getDefaultLibFileName(options: ts.CompilerOptions): string {
|
||||
// return vpath.resolve(this.getDefaultLibLocation(), ts.getDefaultLibFileName(options));
|
||||
|
||||
// TODO(rbuckton): This patches the baseline to replace lib.es5.d.ts with lib.d.ts.
|
||||
// This is only to make the PR for this change easier to read. A follow-up PR will
|
||||
// revert this change and accept the new baselines.
|
||||
// See https://github.com/Microsoft/TypeScript/pull/20763#issuecomment-352553264
|
||||
return vpath.resolve(this.getDefaultLibLocation(), getDefaultLibFileName(options));
|
||||
function getDefaultLibFileName(options: ts.CompilerOptions) {
|
||||
switch (options.target) {
|
||||
case ts.ScriptTarget.ESNext:
|
||||
case ts.ScriptTarget.ES2017:
|
||||
return "lib.es2017.d.ts";
|
||||
case ts.ScriptTarget.ES2016:
|
||||
return "lib.es2016.d.ts";
|
||||
case ts.ScriptTarget.ES2015:
|
||||
return "lib.es2015.d.ts";
|
||||
|
||||
default:
|
||||
return "lib.d.ts";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getSourceFile(fileName: string, languageVersion: number): ts.SourceFile | undefined {
|
||||
const canonicalFileName = this.getCanonicalFileName(vpath.resolve(this.getCurrentDirectory(), fileName));
|
||||
const existing = this._sourceFiles.get(canonicalFileName);
|
||||
if (existing) return existing;
|
||||
|
||||
const content = this.readFile(canonicalFileName);
|
||||
if (content === undefined) return undefined;
|
||||
|
||||
// A virtual file system may shadow another existing virtual file system. This
|
||||
// allows us to reuse a common virtual file system structure across multiple
|
||||
// tests. If a virtual file is a shadow, it is likely that the file will be
|
||||
// reused across multiple tests. In that case, we cache the SourceFile we parse
|
||||
// so that it can be reused across multiple tests to avoid the cost of
|
||||
// repeatedly parsing the same file over and over (such as lib.d.ts).
|
||||
const cacheKey = this.vfs.shadowRoot && `SourceFile[languageVersion=${languageVersion},setParentNodes=${this._setParentNodes}]`;
|
||||
if (cacheKey) {
|
||||
const meta = this.vfs.filemeta(canonicalFileName);
|
||||
const sourceFileFromMetadata = meta.get(cacheKey) as ts.SourceFile | undefined;
|
||||
if (sourceFileFromMetadata) {
|
||||
this._sourceFiles.set(canonicalFileName, sourceFileFromMetadata);
|
||||
return sourceFileFromMetadata;
|
||||
}
|
||||
}
|
||||
|
||||
const parsed = ts.createSourceFile(fileName, content, languageVersion, this._setParentNodes || this.shouldAssertInvariants);
|
||||
if (this.shouldAssertInvariants) {
|
||||
Utils.assertInvariants(parsed, /*parent*/ undefined);
|
||||
}
|
||||
|
||||
this._sourceFiles.set(canonicalFileName, parsed);
|
||||
|
||||
if (cacheKey) {
|
||||
// store the cached source file on the unshadowed file with the same version.
|
||||
const stats = this.vfs.statSync(canonicalFileName);
|
||||
|
||||
let fs = this.vfs;
|
||||
while (fs.shadowRoot) {
|
||||
try {
|
||||
const shadowRootStats = fs.shadowRoot.statSync(canonicalFileName);
|
||||
if (shadowRootStats.dev !== stats.dev ||
|
||||
shadowRootStats.ino !== stats.ino ||
|
||||
shadowRootStats.mtimeMs !== stats.mtimeMs) {
|
||||
break;
|
||||
}
|
||||
|
||||
fs = fs.shadowRoot;
|
||||
}
|
||||
catch {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fs !== this.vfs) {
|
||||
fs.filemeta(canonicalFileName).set(cacheKey, parsed);
|
||||
}
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
// #endregion ServerHost members
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -276,7 +276,7 @@ namespace FourSlash {
|
||||
|
||||
if (configFileName) {
|
||||
const baseDir = ts.normalizePath(ts.getDirectoryPath(configFileName));
|
||||
const host = new compiler.ParseConfigHost(vfsutils.createFromMap(baseDir, /*ignoreCase*/ true, this.inputFiles));
|
||||
const host = new fakes.ParseConfigHost(vfsutils.createFromMap(baseDir, /*ignoreCase*/ true, this.inputFiles));
|
||||
|
||||
const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName));
|
||||
assert.isTrue(configJsonObj.config !== undefined);
|
||||
|
||||
@ -1248,7 +1248,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
return compiler.compileFiles(
|
||||
new compiler.CompilerHost(
|
||||
new fakes.CompilerHost(
|
||||
vfsutils.createFromDocuments(
|
||||
useCaseSensitiveFileNames,
|
||||
inputFiles.concat(otherFiles).map(documents.TextDocument.fromTestFile),
|
||||
|
||||
@ -117,8 +117,8 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
export abstract class LanguageServiceAdapterHost {
|
||||
public typesRegistry: ts.Map<void> | undefined;
|
||||
public readonly vfs = new vfs.FileSystem(/*ignoreCase*/ true, { cwd: virtualFileSystemRoot });
|
||||
public typesRegistry: ts.Map<void> | undefined;
|
||||
private scriptInfos: core.SortedMap<string, ScriptInfo>;
|
||||
|
||||
constructor(protected cancellationToken = DefaultHostCancellationToken.instance,
|
||||
@ -139,17 +139,6 @@ namespace Harness.LanguageService {
|
||||
fileNames.push(scriptInfo.fileName);
|
||||
}
|
||||
});
|
||||
// this.vfs.scanSync("/", "descendants-or-self", {
|
||||
// accept: (path, stats) => {
|
||||
// if (stats.isFile()) {
|
||||
// const scriptInfo = this.vfs.filemeta(path).get("scriptInfo") as ScriptInfo;
|
||||
// if (scriptInfo && scriptInfo.isRootFile) {
|
||||
// fileNames.push(scriptInfo.fileName);
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// });
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
|
||||
@ -72,17 +72,17 @@ namespace project {
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectCompilerHost extends compiler.CompilerHost {
|
||||
class ProjectCompilerHost extends fakes.CompilerHost {
|
||||
private _testCase: ProjectRunnerTestCase & ts.CompilerOptions;
|
||||
private _projectParseConfigHost: ProjectParseConfigHost;
|
||||
|
||||
constructor(vfs: vfs.FileSystem, compilerOptions: ts.CompilerOptions, _testCaseJustName: string, testCase: ProjectRunnerTestCase & ts.CompilerOptions, _moduleKind: ts.ModuleKind) {
|
||||
super(vfs, compilerOptions);
|
||||
constructor(sys: fakes.System | vfs.FileSystem, compilerOptions: ts.CompilerOptions, _testCaseJustName: string, testCase: ProjectRunnerTestCase & ts.CompilerOptions, _moduleKind: ts.ModuleKind) {
|
||||
super(sys, compilerOptions);
|
||||
this._testCase = testCase;
|
||||
}
|
||||
|
||||
public get parseConfigHost(): compiler.ParseConfigHost {
|
||||
return this._projectParseConfigHost || (this._projectParseConfigHost = new ProjectParseConfigHost(this.vfs, this._testCase));
|
||||
public get parseConfigHost(): fakes.ParseConfigHost {
|
||||
return this._projectParseConfigHost || (this._projectParseConfigHost = new ProjectParseConfigHost(this.sys, this._testCase));
|
||||
}
|
||||
|
||||
public getDefaultLibFileName(_options: ts.CompilerOptions) {
|
||||
@ -90,11 +90,11 @@ namespace project {
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectParseConfigHost extends compiler.ParseConfigHost {
|
||||
class ProjectParseConfigHost extends fakes.ParseConfigHost {
|
||||
private _testCase: ProjectRunnerTestCase & ts.CompilerOptions;
|
||||
|
||||
constructor(vfs: vfs.FileSystem, testCase: ProjectRunnerTestCase & ts.CompilerOptions) {
|
||||
super(vfs);
|
||||
constructor(sys: fakes.System, testCase: ProjectRunnerTestCase & ts.CompilerOptions) {
|
||||
super(sys);
|
||||
this._testCase = testCase;
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ namespace project {
|
||||
if (configFileName) {
|
||||
const result = ts.readJsonConfigFile(configFileName, path => vfsutils.readFile(this.vfs, path));
|
||||
configFileSourceFiles.push(result);
|
||||
const configParseHost = new ProjectParseConfigHost(this.vfs, this.testCase);
|
||||
const configParseHost = new ProjectParseConfigHost(new fakes.System(this.vfs), this.testCase);
|
||||
const configParseResult = ts.parseJsonSourceFileConfigFileContent(result, configParseHost, ts.getDirectoryPath(configFileName), this.compilerOptions);
|
||||
inputFiles = configParseResult.fileNames;
|
||||
this.compilerOptions = configParseResult.options;
|
||||
|
||||
@ -115,10 +115,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
const caseInsensitiveBasePath = "c:/dev/";
|
||||
const caseInsensitiveHost = new compiler.ParseConfigHost(createFileSystem(/*ignoreCase*/ true, caseInsensitiveBasePath, "c:/"));
|
||||
const caseInsensitiveHost = new fakes.ParseConfigHost(createFileSystem(/*ignoreCase*/ true, caseInsensitiveBasePath, "c:/"));
|
||||
|
||||
const caseSensitiveBasePath = "/dev/";
|
||||
const caseSensitiveHost = new compiler.ParseConfigHost(createFileSystem(/*ignoreCase*/ false, caseSensitiveBasePath, "/"));
|
||||
const caseSensitiveHost = new fakes.ParseConfigHost(createFileSystem(/*ignoreCase*/ false, caseSensitiveBasePath, "/"));
|
||||
|
||||
function verifyDiagnostics(actual: Diagnostic[], expected: {code: number, category: DiagnosticCategory, messageText: string}[]) {
|
||||
assert.isTrue(expected.length === actual.length, `Expected error: ${JSON.stringify(expected)}. Actual error: ${JSON.stringify(actual)}.`);
|
||||
@ -132,7 +132,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
describe("configurationExtension", () => {
|
||||
forEach<[string, string, compiler.ParseConfigHost], void>([
|
||||
forEach<[string, string, fakes.ParseConfigHost], void>([
|
||||
["under a case insensitive host", caseInsensitiveBasePath, caseInsensitiveHost],
|
||||
["under a case sensitive host", caseSensitiveBasePath, caseSensitiveHost]
|
||||
], ([testName, basePath, host]) => {
|
||||
|
||||
@ -33,7 +33,7 @@ namespace ts {
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" }));
|
||||
const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" }));
|
||||
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
expectedResult.compilerOptions.configFilePath = configFileName;
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ namespace ts {
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" }));
|
||||
const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: "/apath/" }));
|
||||
const { typeAcquisition: actualTypeAcquisition, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
verifyAcquisition(actualTypeAcquisition, expectedResult);
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="tsserverProjectSystem.ts" />
|
||||
/// <reference path="../fakes.ts" />
|
||||
|
||||
namespace ts {
|
||||
interface Range {
|
||||
@ -111,7 +110,7 @@ namespace ts {
|
||||
|
||||
function runBaseline(extension: Extension) {
|
||||
const path = "/a" + extension;
|
||||
const program = makeProgram(path, t.source, includeLib);
|
||||
const program = makeProgram({ path, content: t.source }, includeLib);
|
||||
|
||||
if (hasSyntacticDiagnostics(program)) {
|
||||
// Don't bother generating JS baselines for inputs that aren't valid JS.
|
||||
@ -147,19 +146,17 @@ namespace ts {
|
||||
const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation);
|
||||
data.push(newTextWithRename);
|
||||
|
||||
const diagProgram = makeProgram(path, newText, includeLib);
|
||||
const diagProgram = makeProgram({ path, content: newText }, includeLib);
|
||||
assert.isFalse(hasSyntacticDiagnostics(diagProgram));
|
||||
}
|
||||
return data.join(newLineCharacter);
|
||||
});
|
||||
}
|
||||
|
||||
function makeProgram(path: string, content: string, includeLib?: boolean) {
|
||||
// libFile is expensive to parse repeatedly - only test when required
|
||||
const fs = new vfs.FileSystem(/*ignoreCase*/ true, { files: { [path]: content } });
|
||||
const host = new fakes.ServerHost(fs, { lib: includeLib });
|
||||
function makeProgram(f: { path: string, content: string }, includeLib?: boolean) {
|
||||
const host = projectSystem.createServerHost(includeLib ? [f, projectSystem.libFile] : [f]); // libFile is expensive to parse repeatedly - only test when required
|
||||
const projectService = projectSystem.createProjectService(host);
|
||||
projectService.openClientFile(path);
|
||||
projectService.openClientFile(f.path);
|
||||
const program = projectService.inferredProjects[0].getLanguageService().getProgram();
|
||||
return program;
|
||||
}
|
||||
@ -177,12 +174,15 @@ namespace ts {
|
||||
if (!selectionRange) {
|
||||
throw new Error(`Test ${caption} does not specify selection range`);
|
||||
}
|
||||
const fs = new vfs.FileSystem(/*ignoreCase*/ true, { files: { "/a.ts": t.source } });
|
||||
const host = new fakes.ServerHost(fs, { lib: true });
|
||||
const f = {
|
||||
path: "/a.ts",
|
||||
content: t.source
|
||||
};
|
||||
const host = projectSystem.createServerHost([f, projectSystem.libFile]);
|
||||
const projectService = projectSystem.createProjectService(host);
|
||||
projectService.openClientFile("/a.ts");
|
||||
projectService.openClientFile(f.path);
|
||||
const program = projectService.inferredProjects[0].getLanguageService().getProgram();
|
||||
const sourceFile = program.getSourceFile("/a.ts");
|
||||
const sourceFile = program.getSourceFile(f.path);
|
||||
const context: RefactorContext = {
|
||||
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
|
||||
program,
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
namespace ts {
|
||||
const caseInsensitiveBasePath = "c:/dev/";
|
||||
const caseInsensitiveTsconfigPath = "c:/dev/tsconfig.json";
|
||||
const caseInsensitiveHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
const caseInsensitiveHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
"c:/dev/a.ts": "",
|
||||
"c:/dev/a.d.ts": "",
|
||||
"c:/dev/a.js": "",
|
||||
@ -32,7 +32,7 @@ namespace ts {
|
||||
}}));
|
||||
|
||||
const caseSensitiveBasePath = "/dev/";
|
||||
const caseSensitiveHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: caseSensitiveBasePath, files: {
|
||||
const caseSensitiveHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: caseSensitiveBasePath, files: {
|
||||
"/dev/a.ts": "",
|
||||
"/dev/a.d.ts": "",
|
||||
"/dev/a.js": "",
|
||||
@ -56,7 +56,7 @@ namespace ts {
|
||||
"/dev/js/b.js": "",
|
||||
}}));
|
||||
|
||||
const caseInsensitiveMixedExtensionHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
const caseInsensitiveMixedExtensionHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
"c:/dev/a.ts": "",
|
||||
"c:/dev/a.d.ts": "",
|
||||
"c:/dev/a.js": "",
|
||||
@ -70,7 +70,7 @@ namespace ts {
|
||||
"c:/dev/f.other": "",
|
||||
}}));
|
||||
|
||||
const caseInsensitiveCommonFoldersHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
const caseInsensitiveCommonFoldersHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
"c:/dev/a.ts": "",
|
||||
"c:/dev/a.d.ts": "",
|
||||
"c:/dev/a.js": "",
|
||||
@ -81,7 +81,7 @@ namespace ts {
|
||||
"c:/dev/jspm_packages/a.ts": "",
|
||||
}}));
|
||||
|
||||
const caseInsensitiveDottedFoldersHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
const caseInsensitiveDottedFoldersHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
"c:/dev/x/d.ts": "",
|
||||
"c:/dev/x/y/d.ts": "",
|
||||
"c:/dev/x/y/.e.ts": "",
|
||||
@ -92,13 +92,13 @@ namespace ts {
|
||||
"c:/dev/g.min.js/.g/g.ts": "",
|
||||
}}));
|
||||
|
||||
const caseInsensitiveOrderingDiffersWithCaseHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
const caseInsensitiveOrderingDiffersWithCaseHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: caseInsensitiveBasePath, files: {
|
||||
"c:/dev/xylophone.ts": "",
|
||||
"c:/dev/Yosemite.ts": "",
|
||||
"c:/dev/zebra.ts": "",
|
||||
}}));
|
||||
|
||||
const caseSensitiveOrderingDiffersWithCaseHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: caseSensitiveBasePath, files: {
|
||||
const caseSensitiveOrderingDiffersWithCaseHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: caseSensitiveBasePath, files: {
|
||||
"/dev/xylophone.ts": "",
|
||||
"/dev/Yosemite.ts": "",
|
||||
"/dev/zebra.ts": "",
|
||||
|
||||
@ -36,7 +36,7 @@ namespace ts {
|
||||
"/// <reference path=\"nonexistent4\"/>\n" // No extension
|
||||
);
|
||||
|
||||
const testCompilerHost = new compiler.CompilerHost(
|
||||
const testCompilerHost = new fakes.CompilerHost(
|
||||
vfsutils.createFromDocuments(
|
||||
/*useCaseSensitiveFileNames*/ false,
|
||||
[emptyFile, referenceFile],
|
||||
|
||||
@ -34,14 +34,14 @@ namespace ts {
|
||||
function getParsedCommandJson(jsonText: string, configFileName: string, basePath: string, allFileList: string[]) {
|
||||
const parsed = parseConfigFileTextToJson(configFileName, jsonText);
|
||||
const files = allFileList.reduce((files, value) => (files[value] = "", files), {} as vfs.FileSet);
|
||||
const host: ParseConfigHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: basePath, files: { "/": {}, ...files } }));
|
||||
const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: basePath, files: { "/": {}, ...files } }));
|
||||
return parseJsonConfigFileContent(parsed.config, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
}
|
||||
|
||||
function getParsedCommandJsonNode(jsonText: string, configFileName: string, basePath: string, allFileList: string[]) {
|
||||
const parsed = parseJsonText(configFileName, jsonText);
|
||||
const files = allFileList.reduce((files, value) => (files[value] = "", files), {} as vfs.FileSet);
|
||||
const host: ParseConfigHost = new compiler.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: basePath, files: { "/": {}, ...files } }));
|
||||
const host: ParseConfigHost = new fakes.ParseConfigHost(new vfs.FileSystem(/*ignoreCase*/ false, { cwd: basePath, files: { "/": {}, ...files } }));
|
||||
return parseJsonSourceFileConfigFileContent(parsed, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user