mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 11:54:44 -06:00
Deprecate CompilerResult
This commit is contained in:
parent
4697ba3e50
commit
cd0809e4d6
@ -227,14 +227,22 @@ namespace compiler {
|
||||
public readonly program: ts.Program | undefined;
|
||||
public readonly result: ts.EmitResult | undefined;
|
||||
public readonly options: ts.CompilerOptions;
|
||||
public readonly diagnostics: ts.Diagnostic[];
|
||||
public readonly js: core.KeyedCollection<string, documents.TextDocument>;
|
||||
public readonly dts: core.KeyedCollection<string, documents.TextDocument>;
|
||||
public readonly maps: core.KeyedCollection<string, documents.TextDocument>;
|
||||
public readonly diagnostics: ReadonlyArray<ts.Diagnostic>;
|
||||
public readonly js: core.ReadonlyKeyedCollection<string, documents.TextDocument>;
|
||||
public readonly dts: core.ReadonlyKeyedCollection<string, documents.TextDocument>;
|
||||
public readonly maps: core.ReadonlyKeyedCollection<string, documents.TextDocument>;
|
||||
|
||||
private _inputs: documents.TextDocument[] = [];
|
||||
private _inputsAndOutputs: core.KeyedCollection<string, CompilationOutput>;
|
||||
|
||||
// from CompilerResult
|
||||
public readonly files: ReadonlyArray<Harness.Compiler.GeneratedFile>;
|
||||
public readonly declFilesCode: ReadonlyArray<Harness.Compiler.GeneratedFile>;
|
||||
public readonly sourceMaps: ReadonlyArray<Harness.Compiler.GeneratedFile>;
|
||||
public readonly errors: ReadonlyArray<ts.Diagnostic>;
|
||||
public readonly currentDirectoryForProgram: string;
|
||||
public readonly traceResults: ReadonlyArray<string>;
|
||||
|
||||
constructor(host: CompilerHost, options: ts.CompilerOptions, program: ts.Program | undefined, result: ts.EmitResult | undefined, diagnostics: ts.Diagnostic[]) {
|
||||
this.host = host;
|
||||
this.program = program;
|
||||
@ -243,18 +251,18 @@ namespace compiler {
|
||||
this.options = program ? program.getCompilerOptions() : options;
|
||||
|
||||
// collect outputs
|
||||
this.js = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
|
||||
this.dts = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
|
||||
this.maps = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
|
||||
const js = this.js = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
|
||||
const dts = this.dts = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
|
||||
const maps = this.maps = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
|
||||
for (const document of this.host.outputs) {
|
||||
if (vpath.isJavaScript(document.file)) {
|
||||
this.js.set(document.file, document);
|
||||
js.set(document.file, document);
|
||||
}
|
||||
else if (vpath.isDeclaration(document.file)) {
|
||||
this.dts.set(document.file, document);
|
||||
dts.set(document.file, document);
|
||||
}
|
||||
else if (vpath.isSourceMap(document.file)) {
|
||||
this.maps.set(document.file, document);
|
||||
maps.set(document.file, document);
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,9 +276,9 @@ namespace compiler {
|
||||
if (!vpath.isDeclaration(sourceFile.fileName)) {
|
||||
const outputs = {
|
||||
input,
|
||||
js: this.js.get(this.getOutputPath(sourceFile.fileName, ts.getOutputExtension(sourceFile, this.options))),
|
||||
dts: this.dts.get(this.getOutputPath(sourceFile.fileName, ".d.ts", this.options.declarationDir)),
|
||||
map: this.maps.get(this.getOutputPath(sourceFile.fileName, ts.getOutputExtension(sourceFile, this.options) + ".map"))
|
||||
js: js.get(this.getOutputPath(sourceFile.fileName, ts.getOutputExtension(sourceFile, this.options))),
|
||||
dts: dts.get(this.getOutputPath(sourceFile.fileName, ".d.ts", this.options.declarationDir)),
|
||||
map: maps.get(this.getOutputPath(sourceFile.fileName, ts.getOutputExtension(sourceFile, this.options) + ".map"))
|
||||
};
|
||||
|
||||
this._inputsAndOutputs.set(sourceFile.fileName, outputs);
|
||||
@ -281,9 +289,17 @@ namespace compiler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// from CompilerResult
|
||||
this.files = Array.from(this.js.values(), file => file.asGeneratedFile());
|
||||
this.declFilesCode = Array.from(this.dts.values(), file => file.asGeneratedFile());
|
||||
this.sourceMaps = Array.from(this.maps.values(), file => file.asGeneratedFile());
|
||||
this.errors = diagnostics;
|
||||
this.currentDirectoryForProgram = host.vfs.currentDirectory;
|
||||
this.traceResults = host.traces;
|
||||
}
|
||||
|
||||
public get vfs() {
|
||||
public get vfs(): vfs.VirtualFileSystem {
|
||||
return this.host.vfs;
|
||||
}
|
||||
|
||||
@ -326,6 +342,12 @@ namespace compiler {
|
||||
return outputs && outputs[kind];
|
||||
}
|
||||
|
||||
public getSourceMapRecord(): string | undefined {
|
||||
if (this.result.sourceMaps && this.result.sourceMaps.length > 0) {
|
||||
return Harness.SourceMapRecorder.getSourceMapRecord(this.result.sourceMaps, this.program, this.files);
|
||||
}
|
||||
}
|
||||
|
||||
public getSourceMap(path: string): documents.SourceMap | undefined {
|
||||
if (this.options.noEmit || vpath.isDeclaration(path)) return undefined;
|
||||
if (this.options.inlineSourceMap) {
|
||||
@ -338,7 +360,7 @@ namespace compiler {
|
||||
}
|
||||
}
|
||||
|
||||
public getOutputPath(path: string, ext: string, outDir: string | undefined = this.options.outDir) {
|
||||
public getOutputPath(path: string, ext: string, outDir: string | undefined = this.options.outDir): string {
|
||||
if (outDir) {
|
||||
path = vpath.resolve(this.vfs.currentDirectory, path);
|
||||
const common = this.commonSourceDirectory;
|
||||
@ -352,8 +374,7 @@ namespace compiler {
|
||||
}
|
||||
}
|
||||
|
||||
export function compileFiles(host: CompilerHost, rootFiles: string[] | undefined, compilerOptions: ts.CompilerOptions) {
|
||||
// establish defaults (aligns with old harness)
|
||||
export function compileFiles(host: 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) {
|
||||
@ -368,6 +389,7 @@ namespace compiler {
|
||||
delete compilerOptions.project;
|
||||
}
|
||||
|
||||
// establish defaults (aligns with old harness)
|
||||
if (compilerOptions.target === undefined) compilerOptions.target = ts.ScriptTarget.ES3;
|
||||
if (compilerOptions.newLine === undefined) compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed;
|
||||
if (compilerOptions.skipDefaultLibCheck === undefined) compilerOptions.skipDefaultLibCheck = true;
|
||||
|
||||
@ -108,7 +108,7 @@ class CompilerTest {
|
||||
private lastUnit: Harness.TestCaseParser.TestUnitData;
|
||||
private harnessSettings: Harness.TestCaseParser.CompilerSettings;
|
||||
private hasNonDtsFiles: boolean;
|
||||
private result: Harness.Compiler.CompilerResult;
|
||||
private result: compiler.CompilationResult;
|
||||
private options: ts.CompilerOptions;
|
||||
private tsConfigFiles: Harness.Compiler.TestFile[];
|
||||
// equivalent to the files that will be passed on the command line
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
/// <reference path="./harness.ts" />
|
||||
|
||||
// NOTE: The contents of this file are all exported from the namespace 'core'. This is to
|
||||
// support the eventual conversion of harness into a modular system.
|
||||
|
||||
@ -63,10 +61,20 @@ namespace core {
|
||||
// Collections
|
||||
//
|
||||
|
||||
export interface ReadonlyKeyedCollection<K, V> {
|
||||
readonly size: number;
|
||||
has(key: K): boolean;
|
||||
get(key: K): V | undefined;
|
||||
forEach(callback: (value: V, key: K, collection: this) => void): void;
|
||||
keys(): IterableIterator<K>;
|
||||
values(): IterableIterator<V>;
|
||||
entries(): IterableIterator<[K, V]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of key/value pairs internally sorted by key.
|
||||
*/
|
||||
export class KeyedCollection<K, V> {
|
||||
export class KeyedCollection<K, V> implements ReadonlyKeyedCollection<K, V> {
|
||||
private _comparer: (a: K, b: K) => number;
|
||||
private _keys: K[] = [];
|
||||
private _values: V[] = [];
|
||||
@ -101,7 +109,7 @@ namespace core {
|
||||
insertAt(this._keys, ~index, key);
|
||||
insertAt(this._values, ~index, value);
|
||||
insertAt(this._order, ~index, this._version);
|
||||
this._version++;
|
||||
this.writePostScript();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@ -113,7 +121,7 @@ namespace core {
|
||||
removeAt(this._keys, index);
|
||||
removeAt(this._values, index);
|
||||
removeAt(this._order, index);
|
||||
this._version++;
|
||||
this.writePostScript();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -125,7 +133,7 @@ namespace core {
|
||||
this._keys.length = 0;
|
||||
this._values.length = 0;
|
||||
this._order.length = 0;
|
||||
this._version = 0;
|
||||
this.writePostScript();
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,6 +151,46 @@ namespace core {
|
||||
}
|
||||
}
|
||||
|
||||
public * keys() {
|
||||
const keys = this._keys;
|
||||
const order = this.getInsertionOrder();
|
||||
const version = this._version;
|
||||
this._copyOnWrite = true;
|
||||
for (const index of order) {
|
||||
yield keys[index];
|
||||
}
|
||||
if (version === this._version) {
|
||||
this._copyOnWrite = false;
|
||||
}
|
||||
}
|
||||
|
||||
public * values() {
|
||||
const values = this._values;
|
||||
const order = this.getInsertionOrder();
|
||||
const version = this._version;
|
||||
this._copyOnWrite = true;
|
||||
for (const index of order) {
|
||||
yield values[index];
|
||||
}
|
||||
if (version === this._version) {
|
||||
this._copyOnWrite = false;
|
||||
}
|
||||
}
|
||||
|
||||
public * entries() {
|
||||
const keys = this._keys;
|
||||
const values = this._values;
|
||||
const order = this.getInsertionOrder();
|
||||
const version = this._version;
|
||||
this._copyOnWrite = true;
|
||||
for (const index of order) {
|
||||
yield [keys[index], values[index]] as [K, V];
|
||||
}
|
||||
if (version === this._version) {
|
||||
this._copyOnWrite = false;
|
||||
}
|
||||
}
|
||||
|
||||
private writePreamble() {
|
||||
if (this._copyOnWrite) {
|
||||
this._keys = this._keys.slice();
|
||||
@ -152,10 +200,14 @@ namespace core {
|
||||
}
|
||||
}
|
||||
|
||||
private writePostScript() {
|
||||
this._version++;
|
||||
}
|
||||
|
||||
private getInsertionOrder() {
|
||||
return this._order
|
||||
.map((_, i) => i)
|
||||
.sort((x, y) => compareNumbers(this._order[x], this._order[y]));
|
||||
.sort((x, y) => this._order[x] - this._order[y]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,6 +377,10 @@ namespace core {
|
||||
return length ? text.slice(length) : text;
|
||||
}
|
||||
|
||||
export function addUTF8ByteOrderMark(text: string) {
|
||||
return getByteOrderMarkLength(text) === 0 ? "\u00EF\u00BB\u00BF" + text : text;
|
||||
}
|
||||
|
||||
function splitLinesWorker(text: string, lineStarts: number[] | undefined, lines: string[] | undefined, removeEmptyElements: boolean) {
|
||||
let pos = 0;
|
||||
let end = 0;
|
||||
|
||||
@ -10,6 +10,8 @@ namespace documents {
|
||||
public readonly text: string;
|
||||
|
||||
private _lineStarts: core.LineStarts | undefined;
|
||||
private _testFile: Harness.Compiler.TestFile | undefined;
|
||||
private _generatedFile: Harness.Compiler.GeneratedFile | undefined;
|
||||
|
||||
constructor(file: string, text: string, meta?: Map<string, string>) {
|
||||
this.file = file;
|
||||
@ -20,6 +22,37 @@ namespace documents {
|
||||
public get lineStarts(): core.LineStarts {
|
||||
return this._lineStarts || (this._lineStarts = core.computeLineStarts(this.text));
|
||||
}
|
||||
|
||||
public static fromTestFile(file: Harness.Compiler.TestFile) {
|
||||
return new TextDocument(
|
||||
file.unitName,
|
||||
file.content,
|
||||
file.fileOptions && Object.keys(file.fileOptions)
|
||||
.reduce((meta, key) => meta.set(key, file.fileOptions[key]), new Map<string, string>()));
|
||||
}
|
||||
|
||||
public asTestFile() {
|
||||
return this._testFile || (this._testFile = {
|
||||
unitName: this.file,
|
||||
content: this.text,
|
||||
fileOptions: Array.from(this.meta)
|
||||
.reduce((obj, [key, value]) => (obj[key] = value, obj), {} as Record<string, string>)
|
||||
});
|
||||
}
|
||||
|
||||
public static fromGeneratedFile(file: Harness.Compiler.GeneratedFile) {
|
||||
return new TextDocument(
|
||||
file.fileName,
|
||||
file.writeByteOrderMark ? core.addUTF8ByteOrderMark(file.code) : file.code);
|
||||
}
|
||||
|
||||
public asGeneratedFile() {
|
||||
return this._generatedFile || (this._generatedFile = {
|
||||
fileName: this.file,
|
||||
code: core.removeByteOrderMark(this.text),
|
||||
writeByteOrderMark: core.getByteOrderMarkLength(this.text) > 0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface RawSourceMap {
|
||||
|
||||
@ -482,7 +482,7 @@ namespace Utils {
|
||||
}
|
||||
|
||||
namespace Harness {
|
||||
// tslint:disable-next-line:interface-name
|
||||
// tslint:disable-next-line:interface-name
|
||||
export interface IO {
|
||||
newLine(): string;
|
||||
getCurrentDirectory(): string;
|
||||
@ -1163,7 +1163,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
export interface CompilationOutput {
|
||||
result: CompilerResult;
|
||||
result: compiler.CompilationResult;
|
||||
options: ts.CompilerOptions & HarnessOptions;
|
||||
}
|
||||
|
||||
@ -1208,29 +1208,24 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
const compilation = compiler.compileFiles(
|
||||
const result = compiler.compileFiles(
|
||||
new compiler.CompilerHost(
|
||||
vfs.VirtualFileSystem.createFromTestFiles(
|
||||
{ useCaseSensitiveFileNames, currentDirectory },
|
||||
inputFiles.concat(otherFiles),
|
||||
{ overwrite: true }
|
||||
vfs.VirtualFileSystem.createFromDocuments(
|
||||
useCaseSensitiveFileNames,
|
||||
inputFiles.concat(otherFiles).map(documents.TextDocument.fromTestFile),
|
||||
{ currentDirectory, overwrite: true }
|
||||
),
|
||||
options
|
||||
),
|
||||
programFileNames,
|
||||
options);
|
||||
|
||||
const fileOutputs = compilation.outputs ? compilation.outputs.map(output => (<GeneratedFile>{
|
||||
fileName: output.file,
|
||||
code: core.removeByteOrderMark(output.text),
|
||||
writeByteOrderMark: core.getByteOrderMarkLength(output.text) > 0
|
||||
})) : [];
|
||||
|
||||
const traceResults = compilation.traces && compilation.traces.slice();
|
||||
const program = compilation.program;
|
||||
const emitResult = compilation.result;
|
||||
const errors = compilation.diagnostics;
|
||||
const result = new CompilerResult(fileOutputs, errors, program, compilation.vfs.currentDirectory, emitResult.sourceMaps, traceResults);
|
||||
// const fileOutputs = compilation.outputs.map(output => output.asGeneratedFile());
|
||||
// const traceResults = compilation.traces && compilation.traces.slice();
|
||||
// const program = compilation.program;
|
||||
// const emitResult = compilation.result;
|
||||
// const errors = compilation.diagnostics;
|
||||
// const result = new CompilerResult(fileOutputs, errors, program, compilation.vfs.currentDirectory, emitResult.sourceMaps, traceResults);
|
||||
return { result, options };
|
||||
}
|
||||
|
||||
@ -1242,9 +1237,9 @@ namespace Harness {
|
||||
currentDirectory: string;
|
||||
}
|
||||
|
||||
export function prepareDeclarationCompilationContext(inputFiles: TestFile[],
|
||||
otherFiles: TestFile[],
|
||||
result: CompilerResult,
|
||||
export function prepareDeclarationCompilationContext(inputFiles: ReadonlyArray<TestFile>,
|
||||
otherFiles: ReadonlyArray<TestFile>,
|
||||
result: compiler.CompilationResult,
|
||||
harnessSettings: TestCaseParser.CompilerSettings & HarnessOptions,
|
||||
options: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
@ -1264,10 +1259,10 @@ namespace Harness {
|
||||
}
|
||||
|
||||
function addDtsFile(file: TestFile, dtsFiles: TestFile[]) {
|
||||
if (isDTS(file.unitName)) {
|
||||
if (vpath.isDeclaration(file.unitName)) {
|
||||
dtsFiles.push(file);
|
||||
}
|
||||
else if (isTS(file.unitName)) {
|
||||
else if (vpath.isTypeScript(file.unitName)) {
|
||||
const declFile = findResultCodeFile(file.unitName);
|
||||
if (declFile && !findUnit(declFile.fileName, declInputFiles) && !findUnit(declFile.fileName, declOtherFiles)) {
|
||||
dtsFiles.push({ unitName: declFile.fileName, content: declFile.code });
|
||||
@ -1465,7 +1460,7 @@ namespace Harness {
|
||||
assert.equal(totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length, "total number of errors");
|
||||
}
|
||||
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: TestFile[], errors: ts.Diagnostic[], pretty?: boolean) {
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: ReadonlyArray<TestFile>, errors: ReadonlyArray<ts.Diagnostic>, pretty?: boolean) {
|
||||
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), (): string => {
|
||||
if (!errors || (errors.length === 0)) {
|
||||
/* tslint:disable:no-null-keyword */
|
||||
@ -1611,7 +1606,7 @@ namespace Harness {
|
||||
return file.writeByteOrderMark ? "\u00EF\u00BB\u00BF" : "";
|
||||
}
|
||||
|
||||
export function doSourcemapBaseline(baselinePath: string, options: ts.CompilerOptions, result: CompilerResult, harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
export function doSourcemapBaseline(baselinePath: string, options: ts.CompilerOptions, result: compiler.CompilationResult, harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
if (options.inlineSourceMap) {
|
||||
if (result.sourceMaps.length > 0) {
|
||||
throw new Error("No sourcemap files should be generated if inlineSourceMaps was set.");
|
||||
@ -1642,7 +1637,7 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompilerResult, tsConfigFiles: Harness.Compiler.TestFile[], toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: compiler.CompilationResult, tsConfigFiles: ReadonlyArray<Harness.Compiler.TestFile>, toBeCompiled: ReadonlyArray<Harness.Compiler.TestFile>, otherFiles: ReadonlyArray<Harness.Compiler.TestFile>, harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
if (!options.noEmit && result.files.length === 0 && result.errors.length === 0) {
|
||||
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
|
||||
}
|
||||
@ -1698,7 +1693,7 @@ namespace Harness {
|
||||
return "//// [" + fileName + "]\r\n" + getByteOrderMarkText(file) + utils.removeTestPathPrefixes(file.code);
|
||||
}
|
||||
|
||||
export function collateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): string {
|
||||
export function collateOutputs(outputFiles: ReadonlyArray<Harness.Compiler.GeneratedFile>): string {
|
||||
const gen = iterateOutputs(outputFiles);
|
||||
// Emit them
|
||||
let result = "";
|
||||
@ -1714,9 +1709,9 @@ namespace Harness {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function *iterateOutputs(outputFiles: Harness.Compiler.GeneratedFile[]): IterableIterator<[string, string]> {
|
||||
export function *iterateOutputs(outputFiles: ReadonlyArray<Harness.Compiler.GeneratedFile>): IterableIterator<[string, string]> {
|
||||
// Collect, test, and sort the fileNames
|
||||
outputFiles.sort((a, b) => ts.compareStringsCaseSensitive(cleanName(a.fileName), cleanName(b.fileName)));
|
||||
outputFiles.slice().sort((a, b) => ts.compareStringsCaseSensitive(cleanName(a.fileName), cleanName(b.fileName)));
|
||||
const dupeCase = ts.createMap<number>();
|
||||
// Yield them
|
||||
for (const outputFile of outputFiles) {
|
||||
@ -1751,78 +1746,11 @@ namespace Harness {
|
||||
return path;
|
||||
}
|
||||
|
||||
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
|
||||
export function compileString(_code: string, _unitName: string, _callback: (result: CompilerResult) => void) {
|
||||
// NEWTODO: Re-implement 'compileString'
|
||||
return ts.notImplemented();
|
||||
}
|
||||
|
||||
export interface GeneratedFile {
|
||||
fileName: string;
|
||||
code: string;
|
||||
writeByteOrderMark: boolean;
|
||||
}
|
||||
|
||||
export function isTS(fileName: string) {
|
||||
return ts.endsWith(fileName, ts.Extension.Ts);
|
||||
}
|
||||
|
||||
export function isTSX(fileName: string) {
|
||||
return ts.endsWith(fileName, ts.Extension.Tsx);
|
||||
}
|
||||
|
||||
export function isDTS(fileName: string) {
|
||||
return ts.endsWith(fileName, ts.Extension.Dts);
|
||||
}
|
||||
|
||||
export function isJS(fileName: string) {
|
||||
return ts.endsWith(fileName, ts.Extension.Js);
|
||||
}
|
||||
export function isJSX(fileName: string) {
|
||||
return ts.endsWith(fileName, ts.Extension.Jsx);
|
||||
}
|
||||
|
||||
export function isJSMap(fileName: string) {
|
||||
return ts.endsWith(fileName, ".js.map") || ts.endsWith(fileName, ".jsx.map");
|
||||
}
|
||||
|
||||
/** Contains the code and errors of a compilation and some helper methods to check its status. */
|
||||
export class CompilerResult {
|
||||
public files: GeneratedFile[] = [];
|
||||
public errors: ts.Diagnostic[] = [];
|
||||
public declFilesCode: GeneratedFile[] = [];
|
||||
public sourceMaps: GeneratedFile[] = [];
|
||||
|
||||
/** @param fileResults an array of strings for the fileName and an ITextWriter with its code */
|
||||
constructor(fileResults: GeneratedFile[], errors: ts.Diagnostic[], public program: ts.Program,
|
||||
public currentDirectoryForProgram: string, private sourceMapData: ts.SourceMapData[], public traceResults: string[]) {
|
||||
|
||||
for (const emittedFile of fileResults) {
|
||||
if (isDTS(emittedFile.fileName)) {
|
||||
// .d.ts file, add to declFiles emit
|
||||
this.declFilesCode.push(emittedFile);
|
||||
}
|
||||
else if (isJS(emittedFile.fileName) || isJSX(emittedFile.fileName)) {
|
||||
// .js file, add to files
|
||||
this.files.push(emittedFile);
|
||||
}
|
||||
else if (isJSMap(emittedFile.fileName)) {
|
||||
this.sourceMaps.push(emittedFile);
|
||||
}
|
||||
else {
|
||||
throw new Error("Unrecognized file extension for file " + emittedFile.fileName);
|
||||
}
|
||||
}
|
||||
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
public getSourceMapRecord() {
|
||||
if (this.sourceMapData && this.sourceMapData.length > 0) {
|
||||
return Harness.SourceMapRecorder.getSourceMapRecord(this.sourceMapData, this.program, this.files);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TestCaseParser {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
///<reference path="harness.ts" />
|
||||
///<reference path="runnerbase.ts" />
|
||||
/// <reference path="harness.ts" />
|
||||
/// <reference path="runnerbase.ts" />
|
||||
/// <reference path="./vpath.ts" />
|
||||
|
||||
// Test case is json of below type in tests/cases/project/
|
||||
interface ProjectRunnerTestCase {
|
||||
@ -319,19 +320,19 @@ class ProjectRunner extends RunnerBase {
|
||||
// we need to instead create files that can live in the project reference folder
|
||||
// but make sure extension of these files matches with the fileName the compiler asked to write
|
||||
diskRelativeName = "diskFile" + nonSubfolderDiskFiles +
|
||||
(Harness.Compiler.isDTS(fileName) ? ts.Extension.Dts :
|
||||
Harness.Compiler.isJS(fileName) ? ts.Extension.Js : ".js.map");
|
||||
(vpath.isDeclaration(fileName) ? ts.Extension.Dts :
|
||||
vpath.isJavaScript(fileName) ? ts.Extension.Js : ".js.map");
|
||||
nonSubfolderDiskFiles++;
|
||||
}
|
||||
|
||||
if (Harness.Compiler.isJS(fileName)) {
|
||||
if (vpath.isJavaScript(fileName)) {
|
||||
// Make sure if there is URl we have it cleaned up
|
||||
const indexOfSourceMapUrl = data.lastIndexOf(`//# ${"sourceMappingURL"}=`); // This line can be seen as a sourceMappingURL comment
|
||||
if (indexOfSourceMapUrl !== -1) {
|
||||
data = data.substring(0, indexOfSourceMapUrl + 21) + cleanProjectUrl(data.substring(indexOfSourceMapUrl + 21));
|
||||
}
|
||||
}
|
||||
else if (Harness.Compiler.isJSMap(fileName)) {
|
||||
else if (vpath.isJavaScriptSourceMap(fileName)) {
|
||||
// Make sure sources list is cleaned
|
||||
const sourceMapData = JSON.parse(data);
|
||||
for (let i = 0; i < sourceMapData.sources.length; i++) {
|
||||
|
||||
@ -30,7 +30,7 @@ namespace RWC {
|
||||
let inputFiles: Harness.Compiler.TestFile[] = [];
|
||||
let otherFiles: Harness.Compiler.TestFile[] = [];
|
||||
let tsconfigFiles: Harness.Compiler.TestFile[] = [];
|
||||
let compilerResult: Harness.Compiler.CompilerResult;
|
||||
let compilerResult: compiler.CompilationResult;
|
||||
let compilerOptions: ts.CompilerOptions;
|
||||
const baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
Subfolder: "rwc",
|
||||
|
||||
@ -434,7 +434,7 @@ namespace Harness.SourceMapRecorder {
|
||||
}
|
||||
}
|
||||
|
||||
export function getSourceMapRecord(sourceMapDataList: ts.SourceMapData[], program: ts.Program, jsFiles: Compiler.GeneratedFile[]) {
|
||||
export function getSourceMapRecord(sourceMapDataList: ReadonlyArray<ts.SourceMapData>, program: ts.Program, jsFiles: ReadonlyArray<Compiler.GeneratedFile>) {
|
||||
const sourceMapRecorder = new Compiler.WriterAggregator();
|
||||
|
||||
for (let i = 0; i < sourceMapDataList.length; i++) {
|
||||
|
||||
@ -31,7 +31,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
// Everything declared here should be cleared out in the "after" callback.
|
||||
let testState: {
|
||||
filename: string;
|
||||
compilerResult: Harness.Compiler.CompilerResult;
|
||||
compilerResult: compiler.CompilationResult;
|
||||
inputFiles: Harness.Compiler.TestFile[];
|
||||
};
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="../documents.ts" />
|
||||
/// <reference path="../vfs.ts" />
|
||||
|
||||
namespace ts {
|
||||
@ -23,27 +24,23 @@ namespace ts {
|
||||
const emptyFileName = "empty.ts";
|
||||
const emptyFileRelativePath = "./" + emptyFileName;
|
||||
|
||||
const emptyFile: Harness.Compiler.TestFile = {
|
||||
unitName: emptyFileName,
|
||||
content: ""
|
||||
};
|
||||
const emptyFile = new documents.TextDocument(emptyFileName, "");
|
||||
|
||||
const referenceFileName = "reference.ts";
|
||||
const referenceFileRelativePath = "./" + referenceFileName;
|
||||
|
||||
const referenceFile: Harness.Compiler.TestFile = {
|
||||
unitName: referenceFileName,
|
||||
content:
|
||||
"/// <reference path=\"d:/imaginary/nonexistent1.ts\"/>\n" + // Absolute
|
||||
"/// <reference path=\"./nonexistent2.ts\"/>\n" + // Relative
|
||||
"/// <reference path=\"nonexistent3.ts\"/>\n" + // Unqualified
|
||||
"/// <reference path=\"nonexistent4\"/>\n" // No extension
|
||||
};
|
||||
const referenceFile = new documents.TextDocument(referenceFileName,
|
||||
"/// <reference path=\"d:/imaginary/nonexistent1.ts\"/>\n" + // Absolute
|
||||
"/// <reference path=\"./nonexistent2.ts\"/>\n" + // Relative
|
||||
"/// <reference path=\"nonexistent3.ts\"/>\n" + // Unqualified
|
||||
"/// <reference path=\"nonexistent4\"/>\n" // No extension
|
||||
);
|
||||
|
||||
const testCompilerHost = new compiler.CompilerHost(
|
||||
vfs.VirtualFileSystem.createFromTestFiles(
|
||||
{ useCaseSensitiveFileNames: false, currentDirectory: "d:\\pretend\\" },
|
||||
[emptyFile, referenceFile]),
|
||||
vfs.VirtualFileSystem.createFromDocuments(
|
||||
/*useCaseSensitiveFileNames*/ false,
|
||||
[emptyFile, referenceFile],
|
||||
{ currentDirectory: "d:\\pretend\\" }),
|
||||
{ newLine: NewLineKind.LineFeed });
|
||||
|
||||
it("handles no missing root files", () => {
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
/// <reference path="../compiler/commandLineParser.ts"/>
|
||||
/// <reference path="./harness.ts" />
|
||||
/// <reference path="./core.ts" />
|
||||
/// <reference path="./vpath.ts" />
|
||||
/// <reference path="./events.ts" />
|
||||
/// <reference path="./vpath.ts" />
|
||||
/// <reference path="./documents.ts" />
|
||||
|
||||
// NOTE: The contents of this file are all exported from the namespace 'vfs'. This is to
|
||||
// support the eventual conversion of harness into a modular system.
|
||||
@ -190,7 +191,7 @@ namespace vfs {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a virtual file system with the following directories:
|
||||
* Gets a read-only virtual file system with the following directories:
|
||||
*
|
||||
* | path | physical/virtual |
|
||||
* |:-------|:----------------------|
|
||||
@ -198,7 +199,7 @@ namespace vfs {
|
||||
* | /.lib | physical: tests/lib |
|
||||
* | /.src | virtual |
|
||||
*/
|
||||
public static getBuiltLocal(useCaseSensitiveFileNames: boolean = Harness.IO.useCaseSensitiveFileNames()): VirtualFileSystem {
|
||||
public static getBuiltLocal(useCaseSensitiveFileNames: boolean): VirtualFileSystem {
|
||||
let vfs = useCaseSensitiveFileNames ? this._builtLocalCS : this._builtLocalCI;
|
||||
if (!vfs) {
|
||||
vfs = this._builtLocal;
|
||||
@ -228,27 +229,24 @@ namespace vfs {
|
||||
return vfs;
|
||||
}
|
||||
|
||||
public static createFromOptions(options: { useCaseSensitiveFileNames?: boolean, currentDirectory?: string }) {
|
||||
const vfs = this.getBuiltLocal(options.useCaseSensitiveFileNames).shadow();
|
||||
if (options.currentDirectory) {
|
||||
public static createFromDocuments(useCaseSensitiveFileNames: boolean, documents: documents.TextDocument[], options?: { currentDirectory?: string, overwrite?: boolean }) {
|
||||
const vfs = this.getBuiltLocal(useCaseSensitiveFileNames).shadow();
|
||||
if (options && options.currentDirectory) {
|
||||
vfs.addDirectory(options.currentDirectory);
|
||||
vfs.changeDirectory(options.currentDirectory);
|
||||
}
|
||||
return vfs;
|
||||
}
|
||||
|
||||
public static createFromTestFiles(options: { useCaseSensitiveFileNames?: boolean, currentDirectory?: string }, documents: Harness.Compiler.TestFile[], fileOptions?: { overwrite?: boolean }) {
|
||||
const vfs = this.createFromOptions(options);
|
||||
const fileOptions = options && options.overwrite ? { overwrite: true } : undefined;
|
||||
for (const document of documents) {
|
||||
const file = vfs.addFile(document.unitName, document.content, fileOptions)!;
|
||||
assert.isDefined(file, `Failed to add file: '${document.unitName}'`);
|
||||
const file = vfs.addFile(document.file, document.text, fileOptions)!;
|
||||
assert.isDefined(file, `Failed to add file: '${document.file}'`);
|
||||
file.metadata.set("document", document);
|
||||
// Add symlinks
|
||||
const symlink = document.fileOptions && document.fileOptions.symlink;
|
||||
const symlink = document.meta.get("symlink");
|
||||
if (file && symlink) {
|
||||
for (const link of symlink.split(",")) {
|
||||
const symlink = vfs.addSymlink(vpath.resolve(vfs.currentDirectory, link.trim()), file)!;
|
||||
assert.isDefined(symlink, `Failed to symlink: '${link}'`);
|
||||
assert.isDefined(symlink, `Failed to create symlink: '${link}'`);
|
||||
symlink.metadata.set("document", document);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ namespace vpath {
|
||||
return hasTrailingSeparator(path) ? path.slice(0, -1) : path;
|
||||
}
|
||||
|
||||
function reduce(components: string[]) {
|
||||
function reduce(components: ReadonlyArray<string>) {
|
||||
const normalized = [components[0]];
|
||||
for (let i = 1; i < components.length; i++) {
|
||||
const component = components[i];
|
||||
@ -242,7 +242,7 @@ namespace vpath {
|
||||
/**
|
||||
* Formats a parsed path consisting of a root component and zero or more path segments.
|
||||
*/
|
||||
export function format(components: string[]) {
|
||||
export function format(components: ReadonlyArray<string>) {
|
||||
return components.length ? components[0] + components.slice(1).join(sep) : "";
|
||||
}
|
||||
|
||||
@ -262,31 +262,33 @@ namespace vpath {
|
||||
* Gets the portion of a path following the last separator (`/`).
|
||||
* If the base name has any one of the provided extensions, it is removed.
|
||||
*/
|
||||
export function basename(path: string, extensions: string | string[], ignoreCase: boolean): string;
|
||||
export function basename(path: string, extensions?: string | string[], ignoreCase?: boolean) {
|
||||
export function basename(path: string, extensions: string | ReadonlyArray<string>, ignoreCase: boolean): string;
|
||||
export function basename(path: string, extensions?: string | ReadonlyArray<string>, ignoreCase?: boolean) {
|
||||
path = normalizeSeparators(path);
|
||||
const name = path.substr(Math.max(getRootLength(path), path.lastIndexOf(sep) + 1));
|
||||
const extension = extensions ? extname(path, extensions, ignoreCase) : undefined;
|
||||
return extension ? name.slice(0, name.length - extension.length) : name;
|
||||
}
|
||||
|
||||
const extRegExp = /\.\w+$/;
|
||||
|
||||
function extnameWorker(path: string, extensions: string | string[], stringEqualityComparer: core.EqualityComparer<string>) {
|
||||
function extnameWorker(path: string, extensions: string | ReadonlyArray<string>, stringEqualityComparer: core.EqualityComparer<string>) {
|
||||
const manyExtensions = Array.isArray(extensions) ? extensions : undefined;
|
||||
const singleExtension = Array.isArray(extensions) ? undefined : extensions;
|
||||
const length = manyExtensions ? manyExtensions.length : 1;
|
||||
for (let i = 0; i < length; i++) {
|
||||
let extension = manyExtensions ? manyExtensions[i] : singleExtension;
|
||||
if (!extension.startsWith(".")) extension = "." + extension;
|
||||
if (path.length >= extension.length &&
|
||||
stringEqualityComparer(path.slice(path.length - extension.length), extension)) {
|
||||
return extension;
|
||||
if (path.length >= extension.length && path.charAt(path.length - extension.length) === ".") {
|
||||
const pathExtension = path.slice(path.length - extension.length);
|
||||
if (stringEqualityComparer(pathExtension, extension)) {
|
||||
return pathExtension;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
const extRegExp = /\.\w+$/;
|
||||
|
||||
/**
|
||||
* Gets the file extension for a path.
|
||||
*/
|
||||
@ -294,8 +296,8 @@ namespace vpath {
|
||||
/**
|
||||
* Gets the file extension for a path, provided it is one of the provided extensions.
|
||||
*/
|
||||
export function extname(path: string, extensions: string | string[], ignoreCase: boolean): string;
|
||||
export function extname(path: string, extensions?: string | string[], ignoreCase?: boolean) {
|
||||
export function extname(path: string, extensions: string | ReadonlyArray<string>, ignoreCase: boolean): string;
|
||||
export function extname(path: string, extensions?: string | ReadonlyArray<string>, ignoreCase?: boolean) {
|
||||
if (extensions) {
|
||||
return extnameWorker(path, extensions, ignoreCase ? core.equateStringsCaseInsensitive : core.equateStringsCaseSensitive);
|
||||
}
|
||||
@ -305,32 +307,40 @@ namespace vpath {
|
||||
}
|
||||
|
||||
export function changeExtension(path: string, ext: string): string;
|
||||
export function changeExtension(path: string, ext: string, extensions: string | string[], ignoreCase: boolean): string;
|
||||
export function changeExtension(path: string, ext: string, extensions?: string | string[], ignoreCase?: boolean) {
|
||||
export function changeExtension(path: string, ext: string, extensions: string | ReadonlyArray<string>, ignoreCase: boolean): string;
|
||||
export function changeExtension(path: string, ext: string, extensions?: string | ReadonlyArray<string>, ignoreCase?: boolean) {
|
||||
const pathext = extensions ? extname(path, extensions, ignoreCase) : extname(path);
|
||||
return pathext ? path.slice(0, path.length - pathext.length) + (ext.startsWith(".") ? ext : "." + ext) : path;
|
||||
}
|
||||
|
||||
const typeScriptExtensions: ReadonlyArray<string> = [".ts", ".tsx"];
|
||||
|
||||
export function isTypeScript(path: string) {
|
||||
return path.endsWith(".ts")
|
||||
|| path.endsWith(".tsx");
|
||||
return extname(path, typeScriptExtensions, /*ignoreCase*/ false).length > 0;
|
||||
}
|
||||
|
||||
const javaScriptExtensions: ReadonlyArray<string> = [".js", ".jsx"];
|
||||
|
||||
export function isJavaScript(path: string) {
|
||||
return path.endsWith(".js")
|
||||
|| path.endsWith(".jsx");
|
||||
return extname(path, javaScriptExtensions, /*ignoreCase*/ false).length > 0;
|
||||
}
|
||||
|
||||
export function isDeclaration(path: string) {
|
||||
return path.endsWith(".d.ts");
|
||||
return extname(path, ".d.ts", /*ignoreCase*/ false).length > 0;
|
||||
}
|
||||
|
||||
export function isSourceMap(path: string) {
|
||||
return path.endsWith(".map");
|
||||
return extname(path, ".map", /*ignoreCase*/ false).length > 0;
|
||||
}
|
||||
|
||||
const javaScriptSourceMapExtensions: ReadonlyArray<string> = [".js.map", ".jsx.map"];
|
||||
|
||||
export function isJavaScriptSourceMap(path: string) {
|
||||
return extname(path, javaScriptSourceMapExtensions, /*ignoreCase*/ false).length > 0;
|
||||
}
|
||||
|
||||
export function isJson(path: string) {
|
||||
return path.endsWith(".json");
|
||||
return extname(path, ".json", /*ignoreCase*/ false).length > 0;
|
||||
}
|
||||
|
||||
export function isDefaultLibrary(path: string) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user