Skip to content

Commit cd0809e

Browse files
committed
Deprecate CompilerResult
1 parent 4697ba3 commit cd0809e

12 files changed

+225
-180
lines changed

src/harness/compiler.ts

+39-17
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,22 @@ namespace compiler {
227227
public readonly program: ts.Program | undefined;
228228
public readonly result: ts.EmitResult | undefined;
229229
public readonly options: ts.CompilerOptions;
230-
public readonly diagnostics: ts.Diagnostic[];
231-
public readonly js: core.KeyedCollection<string, documents.TextDocument>;
232-
public readonly dts: core.KeyedCollection<string, documents.TextDocument>;
233-
public readonly maps: core.KeyedCollection<string, documents.TextDocument>;
230+
public readonly diagnostics: ReadonlyArray<ts.Diagnostic>;
231+
public readonly js: core.ReadonlyKeyedCollection<string, documents.TextDocument>;
232+
public readonly dts: core.ReadonlyKeyedCollection<string, documents.TextDocument>;
233+
public readonly maps: core.ReadonlyKeyedCollection<string, documents.TextDocument>;
234234

235235
private _inputs: documents.TextDocument[] = [];
236236
private _inputsAndOutputs: core.KeyedCollection<string, CompilationOutput>;
237237

238+
// from CompilerResult
239+
public readonly files: ReadonlyArray<Harness.Compiler.GeneratedFile>;
240+
public readonly declFilesCode: ReadonlyArray<Harness.Compiler.GeneratedFile>;
241+
public readonly sourceMaps: ReadonlyArray<Harness.Compiler.GeneratedFile>;
242+
public readonly errors: ReadonlyArray<ts.Diagnostic>;
243+
public readonly currentDirectoryForProgram: string;
244+
public readonly traceResults: ReadonlyArray<string>;
245+
238246
constructor(host: CompilerHost, options: ts.CompilerOptions, program: ts.Program | undefined, result: ts.EmitResult | undefined, diagnostics: ts.Diagnostic[]) {
239247
this.host = host;
240248
this.program = program;
@@ -243,18 +251,18 @@ namespace compiler {
243251
this.options = program ? program.getCompilerOptions() : options;
244252

245253
// collect outputs
246-
this.js = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
247-
this.dts = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
248-
this.maps = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
254+
const js = this.js = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
255+
const dts = this.dts = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
256+
const maps = this.maps = new core.KeyedCollection<string, documents.TextDocument>(this.vfs.pathComparer);
249257
for (const document of this.host.outputs) {
250258
if (vpath.isJavaScript(document.file)) {
251-
this.js.set(document.file, document);
259+
js.set(document.file, document);
252260
}
253261
else if (vpath.isDeclaration(document.file)) {
254-
this.dts.set(document.file, document);
262+
dts.set(document.file, document);
255263
}
256264
else if (vpath.isSourceMap(document.file)) {
257-
this.maps.set(document.file, document);
265+
maps.set(document.file, document);
258266
}
259267
}
260268

@@ -268,9 +276,9 @@ namespace compiler {
268276
if (!vpath.isDeclaration(sourceFile.fileName)) {
269277
const outputs = {
270278
input,
271-
js: this.js.get(this.getOutputPath(sourceFile.fileName, ts.getOutputExtension(sourceFile, this.options))),
272-
dts: this.dts.get(this.getOutputPath(sourceFile.fileName, ".d.ts", this.options.declarationDir)),
273-
map: this.maps.get(this.getOutputPath(sourceFile.fileName, ts.getOutputExtension(sourceFile, this.options) + ".map"))
279+
js: js.get(this.getOutputPath(sourceFile.fileName, ts.getOutputExtension(sourceFile, this.options))),
280+
dts: dts.get(this.getOutputPath(sourceFile.fileName, ".d.ts", this.options.declarationDir)),
281+
map: maps.get(this.getOutputPath(sourceFile.fileName, ts.getOutputExtension(sourceFile, this.options) + ".map"))
274282
};
275283

276284
this._inputsAndOutputs.set(sourceFile.fileName, outputs);
@@ -281,9 +289,17 @@ namespace compiler {
281289
}
282290
}
283291
}
292+
293+
// from CompilerResult
294+
this.files = Array.from(this.js.values(), file => file.asGeneratedFile());
295+
this.declFilesCode = Array.from(this.dts.values(), file => file.asGeneratedFile());
296+
this.sourceMaps = Array.from(this.maps.values(), file => file.asGeneratedFile());
297+
this.errors = diagnostics;
298+
this.currentDirectoryForProgram = host.vfs.currentDirectory;
299+
this.traceResults = host.traces;
284300
}
285301

286-
public get vfs() {
302+
public get vfs(): vfs.VirtualFileSystem {
287303
return this.host.vfs;
288304
}
289305

@@ -326,6 +342,12 @@ namespace compiler {
326342
return outputs && outputs[kind];
327343
}
328344

345+
public getSourceMapRecord(): string | undefined {
346+
if (this.result.sourceMaps && this.result.sourceMaps.length > 0) {
347+
return Harness.SourceMapRecorder.getSourceMapRecord(this.result.sourceMaps, this.program, this.files);
348+
}
349+
}
350+
329351
public getSourceMap(path: string): documents.SourceMap | undefined {
330352
if (this.options.noEmit || vpath.isDeclaration(path)) return undefined;
331353
if (this.options.inlineSourceMap) {
@@ -338,7 +360,7 @@ namespace compiler {
338360
}
339361
}
340362

341-
public getOutputPath(path: string, ext: string, outDir: string | undefined = this.options.outDir) {
363+
public getOutputPath(path: string, ext: string, outDir: string | undefined = this.options.outDir): string {
342364
if (outDir) {
343365
path = vpath.resolve(this.vfs.currentDirectory, path);
344366
const common = this.commonSourceDirectory;
@@ -352,8 +374,7 @@ namespace compiler {
352374
}
353375
}
354376

355-
export function compileFiles(host: CompilerHost, rootFiles: string[] | undefined, compilerOptions: ts.CompilerOptions) {
356-
// establish defaults (aligns with old harness)
377+
export function compileFiles(host: CompilerHost, rootFiles: string[] | undefined, compilerOptions: ts.CompilerOptions): CompilationResult {
357378
if (compilerOptions.project || !rootFiles || rootFiles.length === 0) {
358379
const project = readProject(host.parseConfigHost, compilerOptions.project, compilerOptions);
359380
if (project) {
@@ -368,6 +389,7 @@ namespace compiler {
368389
delete compilerOptions.project;
369390
}
370391

392+
// establish defaults (aligns with old harness)
371393
if (compilerOptions.target === undefined) compilerOptions.target = ts.ScriptTarget.ES3;
372394
if (compilerOptions.newLine === undefined) compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed;
373395
if (compilerOptions.skipDefaultLibCheck === undefined) compilerOptions.skipDefaultLibCheck = true;

src/harness/compilerRunner.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class CompilerTest {
108108
private lastUnit: Harness.TestCaseParser.TestUnitData;
109109
private harnessSettings: Harness.TestCaseParser.CompilerSettings;
110110
private hasNonDtsFiles: boolean;
111-
private result: Harness.Compiler.CompilerResult;
111+
private result: compiler.CompilationResult;
112112
private options: ts.CompilerOptions;
113113
private tsConfigFiles: Harness.Compiler.TestFile[];
114114
// equivalent to the files that will be passed on the command line

src/harness/core.ts

+63-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/// <reference path="./harness.ts" />
2-
31
// NOTE: The contents of this file are all exported from the namespace 'core'. This is to
42
// support the eventual conversion of harness into a modular system.
53

@@ -63,10 +61,20 @@ namespace core {
6361
// Collections
6462
//
6563

64+
export interface ReadonlyKeyedCollection<K, V> {
65+
readonly size: number;
66+
has(key: K): boolean;
67+
get(key: K): V | undefined;
68+
forEach(callback: (value: V, key: K, collection: this) => void): void;
69+
keys(): IterableIterator<K>;
70+
values(): IterableIterator<V>;
71+
entries(): IterableIterator<[K, V]>;
72+
}
73+
6674
/**
6775
* A collection of key/value pairs internally sorted by key.
6876
*/
69-
export class KeyedCollection<K, V> {
77+
export class KeyedCollection<K, V> implements ReadonlyKeyedCollection<K, V> {
7078
private _comparer: (a: K, b: K) => number;
7179
private _keys: K[] = [];
7280
private _values: V[] = [];
@@ -101,7 +109,7 @@ namespace core {
101109
insertAt(this._keys, ~index, key);
102110
insertAt(this._values, ~index, value);
103111
insertAt(this._order, ~index, this._version);
104-
this._version++;
112+
this.writePostScript();
105113
}
106114
return this;
107115
}
@@ -113,7 +121,7 @@ namespace core {
113121
removeAt(this._keys, index);
114122
removeAt(this._values, index);
115123
removeAt(this._order, index);
116-
this._version++;
124+
this.writePostScript();
117125
return true;
118126
}
119127
return false;
@@ -125,7 +133,7 @@ namespace core {
125133
this._keys.length = 0;
126134
this._values.length = 0;
127135
this._order.length = 0;
128-
this._version = 0;
136+
this.writePostScript();
129137
}
130138
}
131139

@@ -143,6 +151,46 @@ namespace core {
143151
}
144152
}
145153

154+
public * keys() {
155+
const keys = this._keys;
156+
const order = this.getInsertionOrder();
157+
const version = this._version;
158+
this._copyOnWrite = true;
159+
for (const index of order) {
160+
yield keys[index];
161+
}
162+
if (version === this._version) {
163+
this._copyOnWrite = false;
164+
}
165+
}
166+
167+
public * values() {
168+
const values = this._values;
169+
const order = this.getInsertionOrder();
170+
const version = this._version;
171+
this._copyOnWrite = true;
172+
for (const index of order) {
173+
yield values[index];
174+
}
175+
if (version === this._version) {
176+
this._copyOnWrite = false;
177+
}
178+
}
179+
180+
public * entries() {
181+
const keys = this._keys;
182+
const values = this._values;
183+
const order = this.getInsertionOrder();
184+
const version = this._version;
185+
this._copyOnWrite = true;
186+
for (const index of order) {
187+
yield [keys[index], values[index]] as [K, V];
188+
}
189+
if (version === this._version) {
190+
this._copyOnWrite = false;
191+
}
192+
}
193+
146194
private writePreamble() {
147195
if (this._copyOnWrite) {
148196
this._keys = this._keys.slice();
@@ -152,10 +200,14 @@ namespace core {
152200
}
153201
}
154202

203+
private writePostScript() {
204+
this._version++;
205+
}
206+
155207
private getInsertionOrder() {
156208
return this._order
157209
.map((_, i) => i)
158-
.sort((x, y) => compareNumbers(this._order[x], this._order[y]));
210+
.sort((x, y) => this._order[x] - this._order[y]);
159211
}
160212
}
161213

@@ -325,6 +377,10 @@ namespace core {
325377
return length ? text.slice(length) : text;
326378
}
327379

380+
export function addUTF8ByteOrderMark(text: string) {
381+
return getByteOrderMarkLength(text) === 0 ? "\u00EF\u00BB\u00BF" + text : text;
382+
}
383+
328384
function splitLinesWorker(text: string, lineStarts: number[] | undefined, lines: string[] | undefined, removeEmptyElements: boolean) {
329385
let pos = 0;
330386
let end = 0;

src/harness/documents.ts

+33
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ namespace documents {
1010
public readonly text: string;
1111

1212
private _lineStarts: core.LineStarts | undefined;
13+
private _testFile: Harness.Compiler.TestFile | undefined;
14+
private _generatedFile: Harness.Compiler.GeneratedFile | undefined;
1315

1416
constructor(file: string, text: string, meta?: Map<string, string>) {
1517
this.file = file;
@@ -20,6 +22,37 @@ namespace documents {
2022
public get lineStarts(): core.LineStarts {
2123
return this._lineStarts || (this._lineStarts = core.computeLineStarts(this.text));
2224
}
25+
26+
public static fromTestFile(file: Harness.Compiler.TestFile) {
27+
return new TextDocument(
28+
file.unitName,
29+
file.content,
30+
file.fileOptions && Object.keys(file.fileOptions)
31+
.reduce((meta, key) => meta.set(key, file.fileOptions[key]), new Map<string, string>()));
32+
}
33+
34+
public asTestFile() {
35+
return this._testFile || (this._testFile = {
36+
unitName: this.file,
37+
content: this.text,
38+
fileOptions: Array.from(this.meta)
39+
.reduce((obj, [key, value]) => (obj[key] = value, obj), {} as Record<string, string>)
40+
});
41+
}
42+
43+
public static fromGeneratedFile(file: Harness.Compiler.GeneratedFile) {
44+
return new TextDocument(
45+
file.fileName,
46+
file.writeByteOrderMark ? core.addUTF8ByteOrderMark(file.code) : file.code);
47+
}
48+
49+
public asGeneratedFile() {
50+
return this._generatedFile || (this._generatedFile = {
51+
fileName: this.file,
52+
code: core.removeByteOrderMark(this.text),
53+
writeByteOrderMark: core.getByteOrderMarkLength(this.text) > 0
54+
});
55+
}
2356
}
2457

2558
export interface RawSourceMap {

0 commit comments

Comments
 (0)