Speed up tests by not type-checking lib.d.ts unless the test asks for that.

This commit is contained in:
Cyrus Najmabadi 2015-06-04 01:03:02 -07:00
parent 343a923a35
commit 2bf19e80c3
25 changed files with 139 additions and 106 deletions

View file

@ -506,7 +506,7 @@ function cleanTestDirs() {
// used to pass data from jake command line directly to run.js
function writeTestConfigFile(tests, testConfigFile) {
console.log('Running test(s): ' + tests);
var testConfigContents = '{\n' + '\ttest: [\'' + tests + '\']\n}';
var testConfigContents = JSON.stringify({ test: [tests]});
fs.writeFileSync('test.config', testConfigContents);
}
@ -689,4 +689,4 @@ task('tsc-instrumented', [loggedIOJsPath, instrumenterJsPath, tscFile], function
complete();
});
ex.run();
}, { async: true });
}, { async: true });

View file

@ -11368,6 +11368,12 @@ module ts {
function checkSourceFileWorker(node: SourceFile) {
let links = getNodeLinks(node);
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
links.flags |= NodeCheckFlags.TypeChecked;
if (node.isDefaultLib && compilerOptions.skipDefaultLibCheck) {
return;
}
// Grammar checking
checkGrammarSourceFile(node);
@ -11399,8 +11405,6 @@ module ts {
if (emitParam) {
links.flags |= NodeCheckFlags.EmitParam;
}
links.flags |= NodeCheckFlags.TypeChecked;
}
}

View file

@ -391,6 +391,7 @@ module ts {
processImportedModules(file, basePath);
}
if (isDefaultLib) {
file.isDefaultLib = true;
files.unshift(file);
}
else {

View file

@ -1143,7 +1143,8 @@ module ts {
// The first node that causes this file to be an external module
/* @internal */ externalModuleIndicator: Node;
/* @internal */ isDefaultLib: boolean;
/* @internal */ identifiers: Map<string>;
/* @internal */ nodeCount: number;
/* @internal */ identifierCount: number;
@ -1823,6 +1824,7 @@ module ts {
experimentalDecorators?: boolean;
emitDecoratorMetadata?: boolean;
/* @internal */ stripInternal?: boolean;
/* @internal */ skipDefaultLibCheck?: boolean;
[option: string]: string | number | boolean;
}

View file

@ -808,9 +808,17 @@ module Harness {
}
}
export function createSourceFileAndAssertInvariants(fileName: string, sourceText: string, languageVersion: ts.ScriptTarget, assertInvariants = true) {
export function createSourceFileAndAssertInvariants(
fileName: string,
sourceText: string,
languageVersion: ts.ScriptTarget,
assertInvariants: boolean,
isDefaultLib: boolean) {
// Only set the parent nodes if we're asserting invariants. We don't need them otherwise.
var result = ts.createSourceFile(fileName, sourceText, languageVersion, /*setParentNodes:*/ assertInvariants);
result.isDefaultLib = isDefaultLib;
if (assertInvariants) {
Utils.assertInvariants(result, /*parent:*/ undefined);
}
@ -821,8 +829,8 @@ module Harness {
const lineFeed = "\n";
export var defaultLibFileName = 'lib.d.ts';
export var defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
export var defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest);
export var defaultLibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest, /*assertInvariants:*/ true, /*isDefaultLib:*/ true);
export var defaultES6LibSourceFile = createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + 'lib.core.es6.d.ts'), /*languageVersion*/ ts.ScriptTarget.Latest, /*assertInvariants:*/ true, /*isDefaultLib:*/ true);
// Cache these between executions so we don't have to re-parse them for every test
export var fourslashFileName = 'fourslash.ts';
@ -832,13 +840,14 @@ module Harness {
return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase();
}
export function createCompilerHost(inputFiles: { unitName: string; content: string; }[],
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
scriptTarget: ts.ScriptTarget,
useCaseSensitiveFileNames: boolean,
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
currentDirectory?: string,
newLineKind?: ts.NewLineKind): ts.CompilerHost {
export function createCompilerHost(
inputFiles: { unitName: string; content: string; }[],
writeFile: (fn: string, contents: string, writeByteOrderMark: boolean) => void,
scriptTarget: ts.ScriptTarget,
useCaseSensitiveFileNames: boolean,
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
currentDirectory?: string,
newLineKind?: ts.NewLineKind): ts.CompilerHost {
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
function getCanonicalFileName(fileName: string): string {
@ -852,7 +861,7 @@ module Harness {
function register(file: { unitName: string; content: string; }) {
if (file.content !== undefined) {
var fileName = ts.normalizePath(file.unitName);
filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget, /*assertInvariants:*/ true, /*isDefaultLib:*/ false);
}
};
inputFiles.forEach(register);
@ -875,7 +884,7 @@ module Harness {
}
else if (fn === fourslashFileName) {
var tsFn = 'tests/cases/fourslash/' + fourslashFileName;
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget, /*assertInvariants:*/ true, /*isDefaultLib:*/ false);
return fourslashSourceFile;
}
else {
@ -964,7 +973,8 @@ module Harness {
settingsCallback(null);
}
var newLine = '\r\n';
let newLine = '\r\n';
options.skipDefaultLibCheck = true;
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
// Treat them as library files, so include them in build, but not in baselines.
@ -1050,6 +1060,10 @@ module Harness {
options.outDir = setting.value;
break;
case 'skipdefaultlibcheck':
options.skipDefaultLibCheck = setting.value === "true";
break;
case 'sourceroot':
options.sourceRoot = setting.value;
break;
@ -1134,9 +1148,11 @@ module Harness {
var fileOutputs: GeneratedFile[] = [];
var programFiles = inputFiles.concat(includeBuiltFiles).map(file => file.unitName);
var program = ts.createProgram(programFiles, options, createCompilerHost(inputFiles.concat(includeBuiltFiles).concat(otherFiles),
var compilerHost = createCompilerHost(
inputFiles.concat(includeBuiltFiles).concat(otherFiles),
(fn, contents, writeByteOrderMark) => fileOutputs.push({ fileName: fn, code: contents, writeByteOrderMark: writeByteOrderMark }),
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine));
options.target, useCaseSensitiveFileNames, currentDirectory, options.newLine);
var program = ts.createProgram(programFiles, options, compilerHost);
var emitResult = program.emit();
@ -1480,7 +1496,8 @@ module Harness {
"errortruncation", "usecasesensitivefilenames", "preserveconstenums",
"includebuiltfile", "suppressimplicitanyindexerrors", "stripinternal",
"isolatedmodules", "inlinesourcemap", "maproot", "sourceroot",
"inlinesources", "emitdecoratormetadata", "experimentaldecorators"];
"inlinesources", "emitdecoratormetadata", "experimentaldecorators",
"skipdefaultlibcheck"];
function extractCompilerSettings(content: string): CompilerSetting[] {

View file

@ -174,7 +174,7 @@ class ProjectRunner extends RunnerBase {
else {
var text = getSourceFileText(fileName);
if (text !== undefined) {
sourceFile = Harness.Compiler.createSourceFileAndAssertInvariants(fileName, text, languageVersion);
sourceFile = Harness.Compiler.createSourceFileAndAssertInvariants(fileName, text, languageVersion, /*assertInvariants:*/ true, /*isDefaultLib:*/ false);
}
}

View file

@ -38,41 +38,45 @@ var testConfigFile =
(Harness.IO.fileExists(testconfig) ? Harness.IO.readFile(testconfig) : '');
if (testConfigFile !== '') {
// TODO: not sure why this is crashing mocha
//var testConfig = JSON.parse(testConfigRaw);
var testConfig = testConfigFile.match(/test:\s\['(.*)'\]/);
var options = testConfig ? [testConfig[1]] : [];
for (var i = 0; i < options.length; i++) {
switch (options[i]) {
case 'compiler':
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
runners.push(new ProjectRunner());
break;
case 'conformance':
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
break;
case 'project':
runners.push(new ProjectRunner());
break;
case 'fourslash':
runners.push(new FourSlashRunner(FourSlashTestType.Native));
break;
case 'fourslash-shims':
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
break;
case 'fourslash-server':
runners.push(new FourSlashRunner(FourSlashTestType.Server));
break;
case 'fourslash-generated':
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
break;
case 'rwc':
runners.push(new RWCRunner());
break;
case 'test262':
runners.push(new Test262BaselineRunner());
break;
var testConfig = JSON.parse(testConfigFile);
if (testConfig.test && testConfig.test.length > 0) {
for (let option of testConfig.test) {
if (!option) {
continue;
}
ts.sys.write("Option: " + option + "\r\n");
switch (option) {
case 'compiler':
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
runners.push(new CompilerBaselineRunner(CompilerTestType.Regressions));
runners.push(new ProjectRunner());
break;
case 'conformance':
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));
break;
case 'project':
runners.push(new ProjectRunner());
break;
case 'fourslash':
runners.push(new FourSlashRunner(FourSlashTestType.Native));
break;
case 'fourslash-shims':
runners.push(new FourSlashRunner(FourSlashTestType.Shims));
break;
case 'fourslash-server':
runners.push(new FourSlashRunner(FourSlashTestType.Server));
break;
case 'fourslash-generated':
runners.push(new GeneratedFourslashRunner(FourSlashTestType.Native));
break;
case 'rwc':
runners.push(new RWCRunner());
break;
case 'test262':
runners.push(new Test262BaselineRunner());
break;
}
}
}
}

View file

@ -743,6 +743,7 @@ module ts {
public parseDiagnostics: Diagnostic[];
public bindDiagnostics: Diagnostic[];
public isDefaultLib: boolean;
public hasNoDefaultLib: boolean;
public externalModuleIndicator: Node; // The first node that causes this file to be an external module
public nodeCount: number;

View file

@ -35,14 +35,14 @@ function f1(x: Color | string) {
}
function f2(x: Color | string | string[]) {
>f2 : (x: string | string[] | Color) => void
>x : string | string[] | Color
>f2 : (x: string | Color | string[]) => void
>x : string | Color | string[]
>Color : Color
if (typeof x === "object") {
>typeof x === "object" : boolean
>typeof x : string
>x : string | string[] | Color
>x : string | Color | string[]
>"object" : string
var y = x;
@ -55,7 +55,7 @@ function f2(x: Color | string | string[]) {
if (typeof x === "number") {
>typeof x === "number" : boolean
>typeof x : string
>x : string | string[] | Color
>x : string | Color | string[]
>"number" : string
var z = x;
@ -77,7 +77,7 @@ function f2(x: Color | string | string[]) {
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>x : string | string[] | Color
>x : string | Color | string[]
>"string" : string
var a = x;
@ -89,11 +89,11 @@ function f2(x: Color | string | string[]) {
}
else {
var b = x;
>b : string[] | Color
>x : string[] | Color
>b : Color | string[]
>x : Color | string[]
var b: Color | string[];
>b : string[] | Color
>b : Color | string[]
>Color : Color
}
}

View file

@ -2,8 +2,8 @@
// Empty array literal with no contextual type has type Undefined[]
var arr1= [[], [1], ['']];
>arr1 : (string[] | number[])[]
>[[], [1], ['']] : (string[] | number[])[]
>arr1 : (number[] | string[])[]
>[[], [1], ['']] : (number[] | string[])[]
>[] : undefined[]
>[1] : number[]
>1 : number
@ -11,8 +11,8 @@ var arr1= [[], [1], ['']];
>'' : string
var arr2 = [[null], [1], ['']];
>arr2 : (string[] | number[])[]
>[[null], [1], ['']] : (string[] | number[])[]
>arr2 : (number[] | string[])[]
>[[null], [1], ['']] : (number[] | string[])[]
>[null] : null[]
>null : null
>[1] : number[]

View file

@ -8,8 +8,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(17,5): error
Type '() => string | number | boolean' is not assignable to type '() => number'.
Type 'string | number | boolean' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(32,5): error TS2322: Type '(string[] | number[])[]' is not assignable to type 'tup'.
Property '0' is missing in type '(string[] | number[])[]'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(32,5): error TS2322: Type '(number[] | string[])[]' is not assignable to type 'tup'.
Property '0' is missing in type '(number[] | string[])[]'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(33,5): error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'.
Property '0' is missing in type 'number[]'.
tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error TS2322: Type '(string | number)[]' is not assignable to type 'myArray'.
@ -68,8 +68,8 @@ tests/cases/conformance/expressions/arrayLiterals/arrayLiterals3.ts(34,5): error
interface myArray2 extends Array<Number|String> { }
var c0: tup = [...temp2]; // Error
~~
!!! error TS2322: Type '(string[] | number[])[]' is not assignable to type 'tup'.
!!! error TS2322: Property '0' is missing in type '(string[] | number[])[]'.
!!! error TS2322: Type '(number[] | string[])[]' is not assignable to type 'tup'.
!!! error TS2322: Property '0' is missing in type '(number[] | string[])[]'.
var c1: [number, number, number] = [...temp1]; // Error cannot assign number[] to [number, number, number]
~~
!!! error TS2322: Type 'number[]' is not assignable to type '[number, number, number]'.

View file

@ -17,9 +17,9 @@ declare function foo<T>(obj: I<T>): T
>T : T
foo({
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | number[] | (() => void)
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[]
>foo : <T>(obj: I<T>) => T
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | boolean | number[] | (() => void); 0: () => void; p: string; }
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | boolean | (() => void) | number[]; 0: () => void; p: string; }
p: "",
>p : string

View file

@ -17,9 +17,9 @@ declare function foo<T>(obj: I<T>): T
>T : T
foo({
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | number[] | (() => void)
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[]
>foo : <T>(obj: I<T>) => T
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | boolean | number[] | (() => void); 0: () => void; p: string; }
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | boolean | (() => void) | number[]; 0: () => void; p: string; }
p: "",
>p : string

View file

@ -17,9 +17,9 @@ declare function foo<T>(obj: I<T>): T
>T : T
foo({
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : number | number[] | (() => void)
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : number | (() => void) | number[]
>foo : <T>(obj: I<T>) => T
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: number]: number | number[] | (() => void); 0: () => void; p: string; }
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: number]: number | (() => void) | number[]; 0: () => void; p: string; }
p: "",
>p : string

View file

@ -17,9 +17,9 @@ declare function foo<T>(obj: I<T>): T
>T : T
foo({
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : number | number[] | (() => void)
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : number | (() => void) | number[]
>foo : <T>(obj: I<T>) => T
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: number]: number | number[] | (() => void); 0: () => void; p: string; }
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: number]: number | (() => void) | number[]; 0: () => void; p: string; }
p: "",
>p : string

View file

@ -120,35 +120,35 @@ var b = baz(b, b, g); // Should be number | string
>g : <T>(x: T, y: T) => T
var d: number[] | string[];
>d : string[] | number[]
>d : number[] | string[]
var d = foo(h); // Should be number[] | string[]
>d : string[] | number[]
>foo(h) : string[] | number[]
>d : number[] | string[]
>foo(h) : number[] | string[]
>foo : <T>(cb: (x: number, y: string) => T) => T
>h : <T, U>(x: T, y: U) => T[] | U[]
var d = bar(1, "one", h); // Should be number[] | string[]
>d : string[] | number[]
>bar(1, "one", h) : string[] | number[]
>d : number[] | string[]
>bar(1, "one", h) : number[] | string[]
>bar : <T, U, V>(x: T, y: U, cb: (x: T, y: U) => V) => V
>1 : number
>"one" : string
>h : <T, U>(x: T, y: U) => T[] | U[]
var d = bar("one", 1, h); // Should be number[] | string[]
>d : string[] | number[]
>bar("one", 1, h) : string[] | number[]
>d : number[] | string[]
>bar("one", 1, h) : number[] | string[]
>bar : <T, U, V>(x: T, y: U, cb: (x: T, y: U) => V) => V
>"one" : string
>1 : number
>h : <T, U>(x: T, y: U) => T[] | U[]
var d = baz(d, d, g); // Should be number[] | string[]
>d : string[] | number[]
>baz(d, d, g) : string[] | number[]
>d : number[] | string[]
>baz(d, d, g) : number[] | string[]
>baz : <T, U>(x: T, y: T, cb: (x: T, y: T) => U) => U
>d : string[] | number[]
>d : string[] | number[]
>d : number[] | string[]
>d : number[] | string[]
>g : <T>(x: T, y: T) => T

View file

@ -12,7 +12,7 @@ type arrayString = Array<String>
>String : String
type someArray = Array<String> | number[];
>someArray : number[] | String[]
>someArray : String[] | number[]
>Array : T[]
>String : String

View file

@ -12,7 +12,7 @@ type arrayString = Array<String>
>String : String
type someArray = Array<String> | number[];
>someArray : number[] | String[]
>someArray : String[] | number[]
>Array : T[]
>String : String

View file

@ -40,8 +40,8 @@ var f = [[], [1]]; // number[][]
>1 : number
var g = [[1], ['']]; // {}[]
>g : (string[] | number[])[]
>[[1], ['']] : (string[] | number[])[]
>g : (number[] | string[])[]
>[[1], ['']] : (number[] | string[])[]
>[1] : number[]
>1 : number
>[''] : string[]

View file

@ -379,8 +379,8 @@ var rg7 = a7 || a6; // object || enum is object | enum
>a6 : E
var rg8 = a8 || a6; // array || enum is array | enum
>rg8 : string[] | E
>a8 || a6 : string[] | E
>rg8 : E | string[]
>a8 || a6 : E | string[]
>a8 : string[]
>a6 : E
@ -439,8 +439,8 @@ var rh7 = a7 || a7; // object || object is object
>a7 : { a: string; }
var rh8 = a8 || a7; // array || object is array | object
>rh8 : string[] | { a: string; }
>a8 || a7 : string[] | { a: string; }
>rh8 : { a: string; } | string[]
>a8 || a7 : { a: string; } | string[]
>a8 : string[]
>a7 : { a: string; }
@ -487,14 +487,14 @@ var ri5 = a5 || a8; // void || array is void | array
>a8 : string[]
var ri6 = a6 || a8; // enum || array is enum | array
>ri6 : string[] | E
>a6 || a8 : string[] | E
>ri6 : E | string[]
>a6 || a8 : E | string[]
>a6 : E
>a8 : string[]
var ri7 = a7 || a8; // object || array is object | array
>ri7 : string[] | { a: string; }
>a7 || a8 : string[] | { a: string; }
>ri7 : { a: string; } | string[]
>a7 || a8 : { a: string; } | string[]
>a7 : { a: string; }
>a8 : string[]

View file

@ -363,9 +363,9 @@ function foo12(x: number | string | boolean) {
>10 : number
>x.toString().length : number
>x.toString() : string
>x.toString : () => string
>x.toString : (radix?: number) => string
>x : string | number | boolean
>toString : () => string
>toString : (radix?: number) => string
>length : number
: ((b = x) // x is number | boolean | string - changed in true branch

View file

@ -1,3 +1,4 @@
// @skipDefaultLibCheck: false
"use strict";
function eval() {
}

View file

@ -1,3 +1,4 @@
// @skipDefaultLibCheck: false
// it is an error to have duplicate index signatures of the same kind in a type
interface Number {

View file

@ -1,3 +1,4 @@
// @skipDefaultLibCheck: false
class A {
foo: string;
}

View file

@ -1,3 +1,4 @@
// @skipDefaultLibCheck: false
// object types can define string indexers that are more specific than the default 'any' that would be returned
// no errors expected below