From 7ecf90ee2d38786d7c5d34b1ce85067a5cece070 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Mon, 19 Oct 2015 22:56:00 -0700 Subject: [PATCH 01/31] Fix issue: can't add a file back to a configured project after being deleted once --- src/server/editorServices.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 09f8a372463..4e4b3c84865 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1267,11 +1267,15 @@ namespace ts.server { if (info.isOpen) { if (this.openFileRoots.indexOf(info) >= 0) { this.openFileRoots = copyListRemovingItem(info, this.openFileRoots); + if (info.defaultProject && !info.defaultProject.isConfiguredProject()) { + this.removeProject(info.defaultProject); + } } if (this.openFilesReferenced.indexOf(info) >= 0) { this.openFilesReferenced = copyListRemovingItem(info, this.openFilesReferenced); } this.openFileRootsConfigured.push(info); + info.defaultProject = project; } } project.addRoot(info); From 214e21d05b3291c951122c90dd2ba89287c3f739 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Wed, 21 Oct 2015 13:14:26 -0700 Subject: [PATCH 02/31] Change writeSync to async --- src/compiler/sys.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 3eeb126c065..edf7fa13187 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -370,20 +370,23 @@ namespace ts { } } + function write(buffer: any, offset = 0) { + let toWrite = buffer.length - offset; + _fs.write(1, buffer, offset, toWrite, function(err: any, written: number, buffer: any){ + offset += written; + if (toWrite > written) { + write(buffer, offset); + } + }) + } + return { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, write(s: string): void { const buffer = new Buffer(s, "utf8"); - let offset = 0; - let toWrite: number = buffer.length; - let written = 0; - // 1 is a standard descriptor for stdout - while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) { - offset += written; - toWrite -= written; - } + write(buffer); }, readFile, writeFile, From c072a5fd4b36d53b1e318a33e8fe8c7759347d30 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 21 Oct 2015 16:04:40 -0700 Subject: [PATCH 03/31] `getBaseTypes` handles interfaces merged w/classes Previously it assumed that if a class was present in the merge, only the class base types needed to be used. This became false when classes and interfaces could be merged. --- src/compiler/checker.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bac0553987d..056f21ae945 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2846,22 +2846,24 @@ namespace ts { } function getBaseTypes(type: InterfaceType): ObjectType[] { + let isClass = type.symbol.flags & SymbolFlags.Class; + let isInterface = type.symbol.flags & SymbolFlags.Interface; if (!type.resolvedBaseTypes) { - if (type.symbol.flags & SymbolFlags.Class) { + if (!isClass && !isInterface) { + Debug.fail("type must be class or interface"); + } + if (isClass) { resolveBaseTypesOfClass(type); } - else if (type.symbol.flags & SymbolFlags.Interface) { + if (isInterface) { resolveBaseTypesOfInterface(type); } - else { - Debug.fail("type must be class or interface"); - } } return type.resolvedBaseTypes; } function resolveBaseTypesOfClass(type: InterfaceType): void { - type.resolvedBaseTypes = emptyArray; + type.resolvedBaseTypes = type.resolvedBaseTypes || []; let baseContructorType = getBaseConstructorTypeOfClass(type); if (!(baseContructorType.flags & TypeFlags.ObjectType)) { return; @@ -2897,11 +2899,11 @@ namespace ts { typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); return; } - type.resolvedBaseTypes = [baseType]; + type.resolvedBaseTypes.push(baseType); } function resolveBaseTypesOfInterface(type: InterfaceType): void { - type.resolvedBaseTypes = []; + type.resolvedBaseTypes = type.resolvedBaseTypes || []; for (let declaration of type.symbol.declarations) { if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(declaration)) { for (let node of getInterfaceBaseTypeNodes(declaration)) { From 36ddd022a1f6dc5563cb3dbef8659817f7af0a4a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 21 Oct 2015 16:10:46 -0700 Subject: [PATCH 04/31] Tests for interfaces merged w/classes Both interfaces and classes have base classes/interfaces; all members are available on an instance of the merged child. --- .../mergedInheritedClassInterface.js | 39 ++++++++++ .../mergedInheritedClassInterface.symbols | 75 ++++++++++++++++++ .../mergedInheritedClassInterface.types | 77 +++++++++++++++++++ .../mergedInheritedClassInterface.ts | 27 +++++++ 4 files changed, 218 insertions(+) create mode 100644 tests/baselines/reference/mergedInheritedClassInterface.js create mode 100644 tests/baselines/reference/mergedInheritedClassInterface.symbols create mode 100644 tests/baselines/reference/mergedInheritedClassInterface.types create mode 100644 tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts diff --git a/tests/baselines/reference/mergedInheritedClassInterface.js b/tests/baselines/reference/mergedInheritedClassInterface.js new file mode 100644 index 00000000000..b3a15d1dfba --- /dev/null +++ b/tests/baselines/reference/mergedInheritedClassInterface.js @@ -0,0 +1,39 @@ +//// [mergedInheritedClassInterface.ts] +interface BaseInterface { + required: number; + optional?: number; +} + +declare class BaseClass { + baseMethod(); + x2: number; +} + +interface Child extends BaseInterface { + x3: number; +} + +declare class Child extends BaseClass { + x4: number; + method(); +} + +// checks if properties actually were merged +var child : Child; +child.required; +child.optional; +child.x3; +child.x4; +child.baseMethod(); +child.method(); + + +//// [mergedInheritedClassInterface.js] +// checks if properties actually were merged +var child; +child.required; +child.optional; +child.x3; +child.x4; +child.baseMethod(); +child.method(); diff --git a/tests/baselines/reference/mergedInheritedClassInterface.symbols b/tests/baselines/reference/mergedInheritedClassInterface.symbols new file mode 100644 index 00000000000..27ed4032a5f --- /dev/null +++ b/tests/baselines/reference/mergedInheritedClassInterface.symbols @@ -0,0 +1,75 @@ +=== tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts === +interface BaseInterface { +>BaseInterface : Symbol(BaseInterface, Decl(mergedInheritedClassInterface.ts, 0, 0)) + + required: number; +>required : Symbol(required, Decl(mergedInheritedClassInterface.ts, 0, 25)) + + optional?: number; +>optional : Symbol(optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) +} + +declare class BaseClass { +>BaseClass : Symbol(BaseClass, Decl(mergedInheritedClassInterface.ts, 3, 1)) + + baseMethod(); +>baseMethod : Symbol(baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) + + x2: number; +>x2 : Symbol(x2, Decl(mergedInheritedClassInterface.ts, 6, 17)) +} + +interface Child extends BaseInterface { +>Child : Symbol(Child, Decl(mergedInheritedClassInterface.ts, 8, 1), Decl(mergedInheritedClassInterface.ts, 12, 1)) +>BaseInterface : Symbol(BaseInterface, Decl(mergedInheritedClassInterface.ts, 0, 0)) + + x3: number; +>x3 : Symbol(x3, Decl(mergedInheritedClassInterface.ts, 10, 39)) +} + +declare class Child extends BaseClass { +>Child : Symbol(Child, Decl(mergedInheritedClassInterface.ts, 8, 1), Decl(mergedInheritedClassInterface.ts, 12, 1)) +>BaseClass : Symbol(BaseClass, Decl(mergedInheritedClassInterface.ts, 3, 1)) + + x4: number; +>x4 : Symbol(x4, Decl(mergedInheritedClassInterface.ts, 14, 39)) + + method(); +>method : Symbol(method, Decl(mergedInheritedClassInterface.ts, 15, 15)) +} + +// checks if properties actually were merged +var child : Child; +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>Child : Symbol(Child, Decl(mergedInheritedClassInterface.ts, 8, 1), Decl(mergedInheritedClassInterface.ts, 12, 1)) + +child.required; +>child.required : Symbol(BaseInterface.required, Decl(mergedInheritedClassInterface.ts, 0, 25)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>required : Symbol(BaseInterface.required, Decl(mergedInheritedClassInterface.ts, 0, 25)) + +child.optional; +>child.optional : Symbol(BaseInterface.optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>optional : Symbol(BaseInterface.optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) + +child.x3; +>child.x3 : Symbol(Child.x3, Decl(mergedInheritedClassInterface.ts, 10, 39)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>x3 : Symbol(Child.x3, Decl(mergedInheritedClassInterface.ts, 10, 39)) + +child.x4; +>child.x4 : Symbol(Child.x4, Decl(mergedInheritedClassInterface.ts, 14, 39)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>x4 : Symbol(Child.x4, Decl(mergedInheritedClassInterface.ts, 14, 39)) + +child.baseMethod(); +>child.baseMethod : Symbol(BaseClass.baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>baseMethod : Symbol(BaseClass.baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) + +child.method(); +>child.method : Symbol(Child.method, Decl(mergedInheritedClassInterface.ts, 15, 15)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>method : Symbol(Child.method, Decl(mergedInheritedClassInterface.ts, 15, 15)) + diff --git a/tests/baselines/reference/mergedInheritedClassInterface.types b/tests/baselines/reference/mergedInheritedClassInterface.types new file mode 100644 index 00000000000..bc0f619f843 --- /dev/null +++ b/tests/baselines/reference/mergedInheritedClassInterface.types @@ -0,0 +1,77 @@ +=== tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts === +interface BaseInterface { +>BaseInterface : BaseInterface + + required: number; +>required : number + + optional?: number; +>optional : number +} + +declare class BaseClass { +>BaseClass : BaseClass + + baseMethod(); +>baseMethod : () => any + + x2: number; +>x2 : number +} + +interface Child extends BaseInterface { +>Child : Child +>BaseInterface : BaseInterface + + x3: number; +>x3 : number +} + +declare class Child extends BaseClass { +>Child : Child +>BaseClass : BaseClass + + x4: number; +>x4 : number + + method(); +>method : () => any +} + +// checks if properties actually were merged +var child : Child; +>child : Child +>Child : Child + +child.required; +>child.required : number +>child : Child +>required : number + +child.optional; +>child.optional : number +>child : Child +>optional : number + +child.x3; +>child.x3 : number +>child : Child +>x3 : number + +child.x4; +>child.x4 : number +>child : Child +>x4 : number + +child.baseMethod(); +>child.baseMethod() : any +>child.baseMethod : () => any +>child : Child +>baseMethod : () => any + +child.method(); +>child.method() : any +>child.method : () => any +>child : Child +>method : () => any + diff --git a/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts b/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts new file mode 100644 index 00000000000..593edde7f20 --- /dev/null +++ b/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts @@ -0,0 +1,27 @@ +interface BaseInterface { + required: number; + optional?: number; +} + +declare class BaseClass { + baseMethod(); + x2: number; +} + +interface Child extends BaseInterface { + x3: number; +} + +declare class Child extends BaseClass { + x4: number; + method(); +} + +// checks if properties actually were merged +var child : Child; +child.required; +child.optional; +child.x3; +child.x4; +child.baseMethod(); +child.method(); From 172ff544753e4dc969a8e8740898cfbea64a03ea Mon Sep 17 00:00:00 2001 From: zhengbli Date: Wed, 21 Oct 2015 16:09:16 -0700 Subject: [PATCH 05/31] Move the changes to sys.write to server.ts --- src/compiler/sys.ts | 19 +++++++-------- src/server/server.ts | 56 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index edf7fa13187..3eeb126c065 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -370,23 +370,20 @@ namespace ts { } } - function write(buffer: any, offset = 0) { - let toWrite = buffer.length - offset; - _fs.write(1, buffer, offset, toWrite, function(err: any, written: number, buffer: any){ - offset += written; - if (toWrite > written) { - write(buffer, offset); - } - }) - } - return { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, write(s: string): void { const buffer = new Buffer(s, "utf8"); - write(buffer); + let offset = 0; + let toWrite: number = buffer.length; + let written = 0; + // 1 is a standard descriptor for stdout + while ((written = _fs.writeSync(1, buffer, offset, toWrite)) < toWrite) { + offset += written; + toWrite -= written; + } }, readFile, writeFile, diff --git a/src/server/server.ts b/src/server/server.ts index 39864fc8477..5f181511783 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -11,7 +11,7 @@ namespace ts.server { input: process.stdin, output: process.stdout, terminal: false, - }); + }); class Logger implements ts.server.Logger { fd = -1; @@ -58,7 +58,7 @@ namespace ts.server { isVerbose() { return this.loggingEnabled() && (this.level == "verbose"); } - + msg(s: string, type = "Err") { if (this.fd < 0) { @@ -89,18 +89,18 @@ namespace ts.server { } exit() { - this.projectService.log("Exiting...","Info"); + this.projectService.log("Exiting...", "Info"); this.projectService.closeLog(); process.exit(0); } listen() { - rl.on('line',(input: string) => { + rl.on('line', (input: string) => { var message = input.trim(); this.onMessage(message); }); - rl.on('close',() => { + rl.on('close', () => { this.exit(); }); } @@ -155,6 +155,52 @@ namespace ts.server { var logger = createLoggerFromEnv(); + var messagesToWrite: string[] = []; + function addMessage(message: string) { + messagesToWrite.push(message); + // If the current message list has more than 1 messages, that means + // the current writing is not ended yet, so don't start new writeNext + // as it may interfere with ongoing writing sessions. + if (messagesToWrite.length === 1) { + startWrite(); + } + } + + function startWrite() { + if (messagesToWrite.length === 0) { + return; + } + + let messageToWrite = messagesToWrite[0]; + let buffer = new Buffer(messageToWrite, "utf8"); + write(buffer); + } + + function writeNext() { + if (messagesToWrite.length > 0) { + messagesToWrite = copyListRemovingItem(messagesToWrite[0], messagesToWrite); + } + startWrite(); + } + + function write(buffer: any, offset = 0) { + let toWrite = buffer.length - offset; + fs.write(1, buffer, offset, toWrite, /*position*/undefined, function(err: any, written: number, buffer: any) { + offset += written; + if (toWrite > written) { + // there are some content left that still need to be written + write(buffer, offset); + } + else { + // ready to write the next string + writeNext(); + } + }) + } + + // Override sys.write because fs.writeSync is not reliable on Node 4 + ts.sys.write = (s: string) => addMessage(s); + var ioSession = new IOSession(ts.sys, logger); process.on('uncaughtException', function(err: Error) { ioSession.logError(err, "unknown"); From 7f989315daf0689048109c7000431418a60d70c5 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 21 Oct 2015 16:12:15 -0700 Subject: [PATCH 06/31] Accept baselines A couple of tests were previously updated to give an incorrect error message. --- .../templateStringsArrayTypeDefinedInES5Mode.errors.txt | 8 ++++---- .../templateStringsArrayTypeRedefinedInES6Mode.errors.txt | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/templateStringsArrayTypeDefinedInES5Mode.errors.txt b/tests/baselines/reference/templateStringsArrayTypeDefinedInES5Mode.errors.txt index 94ab5028647..e6910840d39 100644 --- a/tests/baselines/reference/templateStringsArrayTypeDefinedInES5Mode.errors.txt +++ b/tests/baselines/reference/templateStringsArrayTypeDefinedInES5Mode.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/templateStringsArrayTypeDefinedInES5Mode.ts(8,3): error TS2345: Argument of type '{}' is not assignable to parameter of type 'TemplateStringsArray'. - Property 'raw' is missing in type '{}'. +tests/cases/compiler/templateStringsArrayTypeDefinedInES5Mode.ts(8,3): error TS2345: Argument of type '{ [x: number]: undefined; }' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type '{ [x: number]: undefined; }'. ==== tests/cases/compiler/templateStringsArrayTypeDefinedInES5Mode.ts (1 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/templateStringsArrayTypeDefinedInES5Mode.ts(8,3): error TS2 f({}, 10, 10); ~~ -!!! error TS2345: Argument of type '{}' is not assignable to parameter of type 'TemplateStringsArray'. -!!! error TS2345: Property 'raw' is missing in type '{}'. +!!! error TS2345: Argument of type '{ [x: number]: undefined; }' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2345: Property 'raw' is missing in type '{ [x: number]: undefined; }'. f `abcdef${ 1234 }${ 5678 }ghijkl`; \ No newline at end of file diff --git a/tests/baselines/reference/templateStringsArrayTypeRedefinedInES6Mode.errors.txt b/tests/baselines/reference/templateStringsArrayTypeRedefinedInES6Mode.errors.txt index f410d408482..ac30556a235 100644 --- a/tests/baselines/reference/templateStringsArrayTypeRedefinedInES6Mode.errors.txt +++ b/tests/baselines/reference/templateStringsArrayTypeRedefinedInES6Mode.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/templateStringsArrayTypeRedefinedInES6Mode.ts(8,3): error TS2345: Argument of type '{}' is not assignable to parameter of type 'TemplateStringsArray'. - Property 'raw' is missing in type '{}'. +tests/cases/compiler/templateStringsArrayTypeRedefinedInES6Mode.ts(8,3): error TS2345: Argument of type '{ [x: number]: undefined; }' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type '{ [x: number]: undefined; }'. ==== tests/cases/compiler/templateStringsArrayTypeRedefinedInES6Mode.ts (1 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/templateStringsArrayTypeRedefinedInES6Mode.ts(8,3): error T f({}, 10, 10); ~~ -!!! error TS2345: Argument of type '{}' is not assignable to parameter of type 'TemplateStringsArray'. -!!! error TS2345: Property 'raw' is missing in type '{}'. +!!! error TS2345: Argument of type '{ [x: number]: undefined; }' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2345: Property 'raw' is missing in type '{ [x: number]: undefined; }'. f `abcdef${ 1234 }${ 5678 }ghijkl`; \ No newline at end of file From 4d05189d8dbd6807684ff74d5ae502d05bced42a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 21 Oct 2015 16:23:59 -0700 Subject: [PATCH 07/31] Improve naming of test members --- .../mergedInheritedClassInterface.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts b/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts index 593edde7f20..ba1221fc53a 100644 --- a/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts +++ b/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts @@ -5,15 +5,15 @@ interface BaseInterface { declare class BaseClass { baseMethod(); - x2: number; + baseNumber: number; } interface Child extends BaseInterface { - x3: number; + additional: number; } declare class Child extends BaseClass { - x4: number; + classNumber: number; method(); } @@ -21,7 +21,8 @@ declare class Child extends BaseClass { var child : Child; child.required; child.optional; -child.x3; -child.x4; +child.additional; +child.baseNumber; +child.classNumber; child.baseMethod(); child.method(); From ae6ebe155068344517aa3f8619a814b2a47bb946 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 21 Oct 2015 19:55:04 -0700 Subject: [PATCH 08/31] Accept new baselines --- .../mergedInheritedClassInterface.js | 16 +++++---- .../mergedInheritedClassInterface.symbols | 35 +++++++++++-------- .../mergedInheritedClassInterface.types | 29 ++++++++------- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/tests/baselines/reference/mergedInheritedClassInterface.js b/tests/baselines/reference/mergedInheritedClassInterface.js index b3a15d1dfba..fabdeed4960 100644 --- a/tests/baselines/reference/mergedInheritedClassInterface.js +++ b/tests/baselines/reference/mergedInheritedClassInterface.js @@ -6,15 +6,15 @@ interface BaseInterface { declare class BaseClass { baseMethod(); - x2: number; + baseNumber: number; } interface Child extends BaseInterface { - x3: number; + additional: number; } declare class Child extends BaseClass { - x4: number; + classNumber: number; method(); } @@ -22,8 +22,9 @@ declare class Child extends BaseClass { var child : Child; child.required; child.optional; -child.x3; -child.x4; +child.additional; +child.baseNumber; +child.classNumber; child.baseMethod(); child.method(); @@ -33,7 +34,8 @@ child.method(); var child; child.required; child.optional; -child.x3; -child.x4; +child.additional; +child.baseNumber; +child.classNumber; child.baseMethod(); child.method(); diff --git a/tests/baselines/reference/mergedInheritedClassInterface.symbols b/tests/baselines/reference/mergedInheritedClassInterface.symbols index 27ed4032a5f..8746c85da9b 100644 --- a/tests/baselines/reference/mergedInheritedClassInterface.symbols +++ b/tests/baselines/reference/mergedInheritedClassInterface.symbols @@ -15,27 +15,27 @@ declare class BaseClass { baseMethod(); >baseMethod : Symbol(baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) - x2: number; ->x2 : Symbol(x2, Decl(mergedInheritedClassInterface.ts, 6, 17)) + baseNumber: number; +>baseNumber : Symbol(baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 17)) } interface Child extends BaseInterface { >Child : Symbol(Child, Decl(mergedInheritedClassInterface.ts, 8, 1), Decl(mergedInheritedClassInterface.ts, 12, 1)) >BaseInterface : Symbol(BaseInterface, Decl(mergedInheritedClassInterface.ts, 0, 0)) - x3: number; ->x3 : Symbol(x3, Decl(mergedInheritedClassInterface.ts, 10, 39)) + additional: number; +>additional : Symbol(additional, Decl(mergedInheritedClassInterface.ts, 10, 39)) } declare class Child extends BaseClass { >Child : Symbol(Child, Decl(mergedInheritedClassInterface.ts, 8, 1), Decl(mergedInheritedClassInterface.ts, 12, 1)) >BaseClass : Symbol(BaseClass, Decl(mergedInheritedClassInterface.ts, 3, 1)) - x4: number; ->x4 : Symbol(x4, Decl(mergedInheritedClassInterface.ts, 14, 39)) + classNumber: number; +>classNumber : Symbol(classNumber, Decl(mergedInheritedClassInterface.ts, 14, 39)) method(); ->method : Symbol(method, Decl(mergedInheritedClassInterface.ts, 15, 15)) +>method : Symbol(method, Decl(mergedInheritedClassInterface.ts, 15, 24)) } // checks if properties actually were merged @@ -53,15 +53,20 @@ child.optional; >child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) >optional : Symbol(BaseInterface.optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) -child.x3; ->child.x3 : Symbol(Child.x3, Decl(mergedInheritedClassInterface.ts, 10, 39)) +child.additional; +>child.additional : Symbol(Child.additional, Decl(mergedInheritedClassInterface.ts, 10, 39)) >child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) ->x3 : Symbol(Child.x3, Decl(mergedInheritedClassInterface.ts, 10, 39)) +>additional : Symbol(Child.additional, Decl(mergedInheritedClassInterface.ts, 10, 39)) -child.x4; ->child.x4 : Symbol(Child.x4, Decl(mergedInheritedClassInterface.ts, 14, 39)) +child.baseNumber; +>child.baseNumber : Symbol(BaseClass.baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 17)) >child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) ->x4 : Symbol(Child.x4, Decl(mergedInheritedClassInterface.ts, 14, 39)) +>baseNumber : Symbol(BaseClass.baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 17)) + +child.classNumber; +>child.classNumber : Symbol(Child.classNumber, Decl(mergedInheritedClassInterface.ts, 14, 39)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>classNumber : Symbol(Child.classNumber, Decl(mergedInheritedClassInterface.ts, 14, 39)) child.baseMethod(); >child.baseMethod : Symbol(BaseClass.baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) @@ -69,7 +74,7 @@ child.baseMethod(); >baseMethod : Symbol(BaseClass.baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) child.method(); ->child.method : Symbol(Child.method, Decl(mergedInheritedClassInterface.ts, 15, 15)) +>child.method : Symbol(Child.method, Decl(mergedInheritedClassInterface.ts, 15, 24)) >child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) ->method : Symbol(Child.method, Decl(mergedInheritedClassInterface.ts, 15, 15)) +>method : Symbol(Child.method, Decl(mergedInheritedClassInterface.ts, 15, 24)) diff --git a/tests/baselines/reference/mergedInheritedClassInterface.types b/tests/baselines/reference/mergedInheritedClassInterface.types index bc0f619f843..2ad8698ffc3 100644 --- a/tests/baselines/reference/mergedInheritedClassInterface.types +++ b/tests/baselines/reference/mergedInheritedClassInterface.types @@ -15,24 +15,24 @@ declare class BaseClass { baseMethod(); >baseMethod : () => any - x2: number; ->x2 : number + baseNumber: number; +>baseNumber : number } interface Child extends BaseInterface { >Child : Child >BaseInterface : BaseInterface - x3: number; ->x3 : number + additional: number; +>additional : number } declare class Child extends BaseClass { >Child : Child >BaseClass : BaseClass - x4: number; ->x4 : number + classNumber: number; +>classNumber : number method(); >method : () => any @@ -53,15 +53,20 @@ child.optional; >child : Child >optional : number -child.x3; ->child.x3 : number +child.additional; +>child.additional : number >child : Child ->x3 : number +>additional : number -child.x4; ->child.x4 : number +child.baseNumber; +>child.baseNumber : number >child : Child ->x4 : number +>baseNumber : number + +child.classNumber; +>child.classNumber : number +>child : Child +>classNumber : number child.baseMethod(); >child.baseMethod() : any From 56322d2eccf8c9954838c84b13e82d037a7bbc97 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 22 Oct 2015 11:26:19 -0700 Subject: [PATCH 09/31] Root class merged with interface can be extended I found that merging a class that has no base with an interface that has a base class causes a crash because `getDefaultConstructSignatures` assumes that any base must be a class base. Which was true in the previously buggy state. --- src/compiler/checker.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 056f21ae945..fcdb93b01e0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2845,6 +2845,10 @@ namespace ts { return type.resolvedBaseConstructorType; } + function hasClassBaseType(type: InterfaceType): boolean { + return !!forEach(getBaseTypes(type), t => !!(t.symbol.flags & SymbolFlags.Class)); + } + function getBaseTypes(type: InterfaceType): ObjectType[] { let isClass = type.symbol.flags & SymbolFlags.Class; let isInterface = type.symbol.flags & SymbolFlags.Interface; @@ -3254,7 +3258,7 @@ namespace ts { } function getDefaultConstructSignatures(classType: InterfaceType): Signature[] { - if (!getBaseTypes(classType).length) { + if (!hasClassBaseType(classType)) { return [createSignature(undefined, classType.localTypeParameters, emptyArray, classType, undefined, 0, false, false)]; } let baseConstructorType = getBaseConstructorTypeOfClass(classType); From 1651f1809c00f51b96c77dbcadc9ee6f43105809 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 22 Oct 2015 11:32:26 -0700 Subject: [PATCH 10/31] Improve mergedInheritedClassInterface test case Covers the case when the merged interface extends an interface, but the merged class does not extend a class, then trying to extend that class. --- .../mergedInheritedClassInterface.js | 63 ++++++++++++- .../mergedInheritedClassInterface.symbols | 92 ++++++++++++++----- .../mergedInheritedClassInterface.types | 75 ++++++++++++--- .../mergedInheritedClassInterface.ts | 25 ++++- 4 files changed, 214 insertions(+), 41 deletions(-) diff --git a/tests/baselines/reference/mergedInheritedClassInterface.js b/tests/baselines/reference/mergedInheritedClassInterface.js index fabdeed4960..2cc88ac9431 100644 --- a/tests/baselines/reference/mergedInheritedClassInterface.js +++ b/tests/baselines/reference/mergedInheritedClassInterface.js @@ -4,8 +4,8 @@ interface BaseInterface { optional?: number; } -declare class BaseClass { - baseMethod(); +class BaseClass { + baseMethod() { } baseNumber: number; } @@ -13,9 +13,19 @@ interface Child extends BaseInterface { additional: number; } -declare class Child extends BaseClass { +class Child extends BaseClass { classNumber: number; - method(); + method() { } +} + +interface ChildNoBaseClass extends BaseInterface { + additional2: string; +} +class ChildNoBaseClass { + classString: string; + method2() { } +} +class Grandchild extends ChildNoBaseClass { } // checks if properties actually were merged @@ -27,9 +37,48 @@ child.baseNumber; child.classNumber; child.baseMethod(); child.method(); + +var grandchild: Grandchild; +grandchild.required; +grandchild.optional; +grandchild.additional2; +grandchild.classString; +grandchild.method2(); //// [mergedInheritedClassInterface.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var BaseClass = (function () { + function BaseClass() { + } + BaseClass.prototype.baseMethod = function () { }; + return BaseClass; +})(); +var Child = (function (_super) { + __extends(Child, _super); + function Child() { + _super.apply(this, arguments); + } + Child.prototype.method = function () { }; + return Child; +})(BaseClass); +var ChildNoBaseClass = (function () { + function ChildNoBaseClass() { + } + ChildNoBaseClass.prototype.method2 = function () { }; + return ChildNoBaseClass; +})(); +var Grandchild = (function (_super) { + __extends(Grandchild, _super); + function Grandchild() { + _super.apply(this, arguments); + } + return Grandchild; +})(ChildNoBaseClass); // checks if properties actually were merged var child; child.required; @@ -39,3 +88,9 @@ child.baseNumber; child.classNumber; child.baseMethod(); child.method(); +var grandchild; +grandchild.required; +grandchild.optional; +grandchild.additional2; +grandchild.classString; +grandchild.method2(); diff --git a/tests/baselines/reference/mergedInheritedClassInterface.symbols b/tests/baselines/reference/mergedInheritedClassInterface.symbols index 8746c85da9b..5f4ae67df6f 100644 --- a/tests/baselines/reference/mergedInheritedClassInterface.symbols +++ b/tests/baselines/reference/mergedInheritedClassInterface.symbols @@ -9,14 +9,14 @@ interface BaseInterface { >optional : Symbol(optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) } -declare class BaseClass { +class BaseClass { >BaseClass : Symbol(BaseClass, Decl(mergedInheritedClassInterface.ts, 3, 1)) - baseMethod(); ->baseMethod : Symbol(baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) + baseMethod() { } +>baseMethod : Symbol(baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 17)) baseNumber: number; ->baseNumber : Symbol(baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 17)) +>baseNumber : Symbol(baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 20)) } interface Child extends BaseInterface { @@ -27,54 +27,104 @@ interface Child extends BaseInterface { >additional : Symbol(additional, Decl(mergedInheritedClassInterface.ts, 10, 39)) } -declare class Child extends BaseClass { +class Child extends BaseClass { >Child : Symbol(Child, Decl(mergedInheritedClassInterface.ts, 8, 1), Decl(mergedInheritedClassInterface.ts, 12, 1)) >BaseClass : Symbol(BaseClass, Decl(mergedInheritedClassInterface.ts, 3, 1)) classNumber: number; ->classNumber : Symbol(classNumber, Decl(mergedInheritedClassInterface.ts, 14, 39)) +>classNumber : Symbol(classNumber, Decl(mergedInheritedClassInterface.ts, 14, 31)) - method(); + method() { } >method : Symbol(method, Decl(mergedInheritedClassInterface.ts, 15, 24)) } +interface ChildNoBaseClass extends BaseInterface { +>ChildNoBaseClass : Symbol(ChildNoBaseClass, Decl(mergedInheritedClassInterface.ts, 17, 1), Decl(mergedInheritedClassInterface.ts, 21, 1)) +>BaseInterface : Symbol(BaseInterface, Decl(mergedInheritedClassInterface.ts, 0, 0)) + + additional2: string; +>additional2 : Symbol(additional2, Decl(mergedInheritedClassInterface.ts, 19, 50)) +} +class ChildNoBaseClass { +>ChildNoBaseClass : Symbol(ChildNoBaseClass, Decl(mergedInheritedClassInterface.ts, 17, 1), Decl(mergedInheritedClassInterface.ts, 21, 1)) + + classString: string; +>classString : Symbol(classString, Decl(mergedInheritedClassInterface.ts, 22, 24)) + + method2() { } +>method2 : Symbol(method2, Decl(mergedInheritedClassInterface.ts, 23, 24)) +} +class Grandchild extends ChildNoBaseClass { +>Grandchild : Symbol(Grandchild, Decl(mergedInheritedClassInterface.ts, 25, 1)) +>ChildNoBaseClass : Symbol(ChildNoBaseClass, Decl(mergedInheritedClassInterface.ts, 17, 1), Decl(mergedInheritedClassInterface.ts, 21, 1)) +} + // checks if properties actually were merged var child : Child; ->child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 30, 3)) >Child : Symbol(Child, Decl(mergedInheritedClassInterface.ts, 8, 1), Decl(mergedInheritedClassInterface.ts, 12, 1)) child.required; >child.required : Symbol(BaseInterface.required, Decl(mergedInheritedClassInterface.ts, 0, 25)) ->child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 30, 3)) >required : Symbol(BaseInterface.required, Decl(mergedInheritedClassInterface.ts, 0, 25)) child.optional; >child.optional : Symbol(BaseInterface.optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) ->child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 30, 3)) >optional : Symbol(BaseInterface.optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) child.additional; >child.additional : Symbol(Child.additional, Decl(mergedInheritedClassInterface.ts, 10, 39)) ->child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 30, 3)) >additional : Symbol(Child.additional, Decl(mergedInheritedClassInterface.ts, 10, 39)) child.baseNumber; ->child.baseNumber : Symbol(BaseClass.baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 17)) ->child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) ->baseNumber : Symbol(BaseClass.baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 17)) +>child.baseNumber : Symbol(BaseClass.baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 20)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 30, 3)) +>baseNumber : Symbol(BaseClass.baseNumber, Decl(mergedInheritedClassInterface.ts, 6, 20)) child.classNumber; ->child.classNumber : Symbol(Child.classNumber, Decl(mergedInheritedClassInterface.ts, 14, 39)) ->child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) ->classNumber : Symbol(Child.classNumber, Decl(mergedInheritedClassInterface.ts, 14, 39)) +>child.classNumber : Symbol(Child.classNumber, Decl(mergedInheritedClassInterface.ts, 14, 31)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 30, 3)) +>classNumber : Symbol(Child.classNumber, Decl(mergedInheritedClassInterface.ts, 14, 31)) child.baseMethod(); ->child.baseMethod : Symbol(BaseClass.baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) ->child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) ->baseMethod : Symbol(BaseClass.baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 25)) +>child.baseMethod : Symbol(BaseClass.baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 17)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 30, 3)) +>baseMethod : Symbol(BaseClass.baseMethod, Decl(mergedInheritedClassInterface.ts, 5, 17)) child.method(); >child.method : Symbol(Child.method, Decl(mergedInheritedClassInterface.ts, 15, 24)) ->child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 20, 3)) +>child : Symbol(child, Decl(mergedInheritedClassInterface.ts, 30, 3)) >method : Symbol(Child.method, Decl(mergedInheritedClassInterface.ts, 15, 24)) +var grandchild: Grandchild; +>grandchild : Symbol(grandchild, Decl(mergedInheritedClassInterface.ts, 39, 3)) +>Grandchild : Symbol(Grandchild, Decl(mergedInheritedClassInterface.ts, 25, 1)) + +grandchild.required; +>grandchild.required : Symbol(BaseInterface.required, Decl(mergedInheritedClassInterface.ts, 0, 25)) +>grandchild : Symbol(grandchild, Decl(mergedInheritedClassInterface.ts, 39, 3)) +>required : Symbol(BaseInterface.required, Decl(mergedInheritedClassInterface.ts, 0, 25)) + +grandchild.optional; +>grandchild.optional : Symbol(BaseInterface.optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) +>grandchild : Symbol(grandchild, Decl(mergedInheritedClassInterface.ts, 39, 3)) +>optional : Symbol(BaseInterface.optional, Decl(mergedInheritedClassInterface.ts, 1, 21)) + +grandchild.additional2; +>grandchild.additional2 : Symbol(ChildNoBaseClass.additional2, Decl(mergedInheritedClassInterface.ts, 19, 50)) +>grandchild : Symbol(grandchild, Decl(mergedInheritedClassInterface.ts, 39, 3)) +>additional2 : Symbol(ChildNoBaseClass.additional2, Decl(mergedInheritedClassInterface.ts, 19, 50)) + +grandchild.classString; +>grandchild.classString : Symbol(ChildNoBaseClass.classString, Decl(mergedInheritedClassInterface.ts, 22, 24)) +>grandchild : Symbol(grandchild, Decl(mergedInheritedClassInterface.ts, 39, 3)) +>classString : Symbol(ChildNoBaseClass.classString, Decl(mergedInheritedClassInterface.ts, 22, 24)) + +grandchild.method2(); +>grandchild.method2 : Symbol(ChildNoBaseClass.method2, Decl(mergedInheritedClassInterface.ts, 23, 24)) +>grandchild : Symbol(grandchild, Decl(mergedInheritedClassInterface.ts, 39, 3)) +>method2 : Symbol(ChildNoBaseClass.method2, Decl(mergedInheritedClassInterface.ts, 23, 24)) + diff --git a/tests/baselines/reference/mergedInheritedClassInterface.types b/tests/baselines/reference/mergedInheritedClassInterface.types index 2ad8698ffc3..e7e645fb278 100644 --- a/tests/baselines/reference/mergedInheritedClassInterface.types +++ b/tests/baselines/reference/mergedInheritedClassInterface.types @@ -9,11 +9,11 @@ interface BaseInterface { >optional : number } -declare class BaseClass { +class BaseClass { >BaseClass : BaseClass - baseMethod(); ->baseMethod : () => any + baseMethod() { } +>baseMethod : () => void baseNumber: number; >baseNumber : number @@ -27,15 +27,36 @@ interface Child extends BaseInterface { >additional : number } -declare class Child extends BaseClass { +class Child extends BaseClass { >Child : Child >BaseClass : BaseClass classNumber: number; >classNumber : number - method(); ->method : () => any + method() { } +>method : () => void +} + +interface ChildNoBaseClass extends BaseInterface { +>ChildNoBaseClass : ChildNoBaseClass +>BaseInterface : BaseInterface + + additional2: string; +>additional2 : string +} +class ChildNoBaseClass { +>ChildNoBaseClass : ChildNoBaseClass + + classString: string; +>classString : string + + method2() { } +>method2 : () => void +} +class Grandchild extends ChildNoBaseClass { +>Grandchild : Grandchild +>ChildNoBaseClass : ChildNoBaseClass } // checks if properties actually were merged @@ -69,14 +90,44 @@ child.classNumber; >classNumber : number child.baseMethod(); ->child.baseMethod() : any ->child.baseMethod : () => any +>child.baseMethod() : void +>child.baseMethod : () => void >child : Child ->baseMethod : () => any +>baseMethod : () => void child.method(); ->child.method() : any ->child.method : () => any +>child.method() : void +>child.method : () => void >child : Child ->method : () => any +>method : () => void + +var grandchild: Grandchild; +>grandchild : Grandchild +>Grandchild : Grandchild + +grandchild.required; +>grandchild.required : number +>grandchild : Grandchild +>required : number + +grandchild.optional; +>grandchild.optional : number +>grandchild : Grandchild +>optional : number + +grandchild.additional2; +>grandchild.additional2 : string +>grandchild : Grandchild +>additional2 : string + +grandchild.classString; +>grandchild.classString : string +>grandchild : Grandchild +>classString : string + +grandchild.method2(); +>grandchild.method2() : void +>grandchild.method2 : () => void +>grandchild : Grandchild +>method2 : () => void diff --git a/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts b/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts index ba1221fc53a..e3bc08e3307 100644 --- a/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts +++ b/tests/cases/conformance/classes/classDeclarations/mergedInheritedClassInterface.ts @@ -3,8 +3,8 @@ interface BaseInterface { optional?: number; } -declare class BaseClass { - baseMethod(); +class BaseClass { + baseMethod() { } baseNumber: number; } @@ -12,9 +12,19 @@ interface Child extends BaseInterface { additional: number; } -declare class Child extends BaseClass { +class Child extends BaseClass { classNumber: number; - method(); + method() { } +} + +interface ChildNoBaseClass extends BaseInterface { + additional2: string; +} +class ChildNoBaseClass { + classString: string; + method2() { } +} +class Grandchild extends ChildNoBaseClass { } // checks if properties actually were merged @@ -26,3 +36,10 @@ child.baseNumber; child.classNumber; child.baseMethod(); child.method(); + +var grandchild: Grandchild; +grandchild.required; +grandchild.optional; +grandchild.additional2; +grandchild.classString; +grandchild.method2(); From 6dda170e13b7fc4edb4c05b0048cf6e5fe52da55 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Thu, 22 Oct 2015 11:54:45 -0700 Subject: [PATCH 11/31] cache results of fileExists check in default compiler host --- src/compiler/program.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index d76e7585d15..85a43ac537f 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -209,6 +209,7 @@ namespace ts { export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost { let currentDirectory: string; let existingDirectories: Map = {}; + let existingFiles: Map = {}; function getCanonicalFileName(fileName: string): string { // if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form. @@ -249,6 +250,14 @@ namespace ts { return false; } + function fileExists(fileName: string): boolean { + if (hasProperty(existingFiles, fileName)) { + return existingFiles[fileName]; + } + + return existingFiles[fileName] = sys.fileExists(fileName); + } + function ensureDirectoriesExist(directoryPath: string) { if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) { let parentDirectory = getDirectoryPath(directoryPath); @@ -281,7 +290,7 @@ namespace ts { useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames, getCanonicalFileName, getNewLine: () => newLine, - fileExists: fileName => sys.fileExists(fileName), + fileExists, readFile: fileName => sys.readFile(fileName) }; } From 7158a65b1529833321c61d7b1a8e6e760afd4bb9 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Thu, 22 Oct 2015 13:22:45 -0700 Subject: [PATCH 12/31] move 'fileExists' caching to tsc --- src/compiler/program.ts | 11 +---------- src/compiler/tsc.ts | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 85a43ac537f..d76e7585d15 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -209,7 +209,6 @@ namespace ts { export function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost { let currentDirectory: string; let existingDirectories: Map = {}; - let existingFiles: Map = {}; function getCanonicalFileName(fileName: string): string { // if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form. @@ -250,14 +249,6 @@ namespace ts { return false; } - function fileExists(fileName: string): boolean { - if (hasProperty(existingFiles, fileName)) { - return existingFiles[fileName]; - } - - return existingFiles[fileName] = sys.fileExists(fileName); - } - function ensureDirectoriesExist(directoryPath: string) { if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) { let parentDirectory = getDirectoryPath(directoryPath); @@ -290,7 +281,7 @@ namespace ts { useCaseSensitiveFileNames: () => sys.useCaseSensitiveFileNames, getCanonicalFileName, getNewLine: () => newLine, - fileExists, + fileExists: fileName => sys.fileExists(fileName), readFile: fileName => sys.readFile(fileName) }; } diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index e51fda074c5..a72b5bb1b06 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -159,6 +159,9 @@ namespace ts { let timerHandleForRecompilation: number; // Handle for 0.25s wait timer to trigger recompilation let timerHandleForDirectoryChanges: number; // Handle for 0.25s wait timer to trigger directory change handler + let cachedExistingFiles: Map; + let hostFileExists: typeof compilerHost.fileExists; + if (commandLine.options.locale) { if (!isJSONSupported()) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale")); @@ -274,8 +277,14 @@ namespace ts { compilerHost = createCompilerHost(compilerOptions); hostGetSourceFile = compilerHost.getSourceFile; compilerHost.getSourceFile = getSourceFile; + + hostFileExists = compilerHost.fileExists; + compilerHost.fileExists = fileExists; } + // reset the cache of existing files + cachedExistingFiles = {}; + let compileResult = compile(rootFileNames, compilerOptions, compilerHost); if (!compilerOptions.watch) { @@ -286,6 +295,13 @@ namespace ts { reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes)); } + function fileExists(fileName: string): boolean { + if (hasProperty(cachedExistingFiles, fileName)) { + return cachedExistingFiles[fileName]; + } + return cachedExistingFiles[fileName] = hostFileExists(fileName); + } + function getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void) { // Return existing SourceFile object if one is available if (cachedProgram) { From 36050cdefd242d9152c587176bfc58052b2b1294 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 22 Oct 2015 13:23:12 -0700 Subject: [PATCH 13/31] Update diagnostic text to use ES2015, not ES6. --- src/compiler/commandLineParser.ts | 8 ++++---- src/compiler/diagnosticMessages.json | 24 ++++++++++++------------ src/compiler/program.ts | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 0c561ab06d8..58e72241374 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -79,9 +79,9 @@ namespace ts { "es6": ModuleKind.ES6, "es2015": ModuleKind.ES2015, }, - description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es6, + description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015, paramType: Diagnostics.KIND, - error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_or_es6 + error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_or_es2015 }, { name: "newLine", @@ -212,9 +212,9 @@ namespace ts { "es6": ScriptTarget.ES6, "es2015": ScriptTarget.ES2015, }, - description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES6_experimental, + description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_experimental, paramType: Diagnostics.VERSION, - error: Diagnostics.Argument_for_target_option_must_be_ES3_ES5_or_ES6 + error: Diagnostics.Argument_for_target_option_must_be_ES3_ES5_or_ES2015 }, { name: "version", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 188cf23f76c..9ea9514b4af 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -627,7 +627,7 @@ "category": "Error", "code": 1203 }, - "Cannot compile modules into 'es6' when targeting 'ES5' or lower.": { + "Cannot compile modules into 'es2015' when targeting 'ES5' or lower.": { "category": "Error", "code": 1204 }, @@ -2044,7 +2044,7 @@ "category": "Error", "code": 5042 }, - "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher.": { + "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher.": { "category": "Error", "code": 5047 }, @@ -2105,11 +2105,11 @@ "category": "Message", "code": 6010 }, - "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES6' (experimental)": { - "category": "Message", - "code": 6015 - }, - "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es6'": { + "Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015' (experimental)": { + "category": "Message", + "code": 6015 + }, + "Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'": { "category": "Message", "code": 6016 }, @@ -2193,14 +2193,14 @@ "category": "Error", "code": 6045 }, - "Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', or 'es6'.": { + "Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', or 'es2015'.": { "category": "Error", "code": 6046 }, - "Argument for '--target' option must be 'ES3', 'ES5', or 'ES6'.": { - "category": "Error", - "code": 6047 - }, + "Argument for '--target' option must be 'ES3', 'ES5', or 'ES2015'.": { + "category": "Error", + "code": 6047 + }, "Locale must be of the form or -. For example '{0}' or '{1}'.": { "category": "Error", "code": 6048 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index d76e7585d15..17187189bb7 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1005,7 +1005,7 @@ namespace ts { let firstExternalModuleSourceFile = forEach(files, f => isExternalModule(f) ? f : undefined); if (options.isolatedModules) { if (!options.module && languageVersion < ScriptTarget.ES6) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES6_or_higher)); + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher)); } let firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !isDeclarationFile(f) ? f : undefined); @@ -1022,7 +1022,7 @@ namespace ts { // Cannot specify module gen target of es6 when below es6 if (options.module === ModuleKind.ES6 && languageVersion < ScriptTarget.ES6) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_es6_when_targeting_ES5_or_lower)); + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_modules_into_es2015_when_targeting_ES5_or_lower)); } // there has to be common source directory if user specified --outdir || --sourceRoot From f99227b330b44ff9cd7eaf2fd0aa75819246feef Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 22 Oct 2015 13:28:54 -0700 Subject: [PATCH 14/31] Accept baselines --- tests/baselines/reference/es5andes6module.errors.txt | 4 ++-- .../reference/isolatedModulesUnspecifiedModule.errors.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/es5andes6module.errors.txt b/tests/baselines/reference/es5andes6module.errors.txt index d5a672b9486..6908bfc8ae6 100644 --- a/tests/baselines/reference/es5andes6module.errors.txt +++ b/tests/baselines/reference/es5andes6module.errors.txt @@ -1,7 +1,7 @@ -error TS1204: Cannot compile modules into 'es6' when targeting 'ES5' or lower. +error TS1204: Cannot compile modules into 'es2015' when targeting 'ES5' or lower. -!!! error TS1204: Cannot compile modules into 'es6' when targeting 'ES5' or lower. +!!! error TS1204: Cannot compile modules into 'es2015' when targeting 'ES5' or lower. ==== tests/cases/compiler/es5andes6module.ts (0 errors) ==== export default class A diff --git a/tests/baselines/reference/isolatedModulesUnspecifiedModule.errors.txt b/tests/baselines/reference/isolatedModulesUnspecifiedModule.errors.txt index 7d290bcae44..1abc6ca47d4 100644 --- a/tests/baselines/reference/isolatedModulesUnspecifiedModule.errors.txt +++ b/tests/baselines/reference/isolatedModulesUnspecifiedModule.errors.txt @@ -1,6 +1,6 @@ -error TS5047: Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher. +error TS5047: Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher. -!!! error TS5047: Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher. +!!! error TS5047: Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher. ==== tests/cases/compiler/isolatedModulesUnspecifiedModule.ts (0 errors) ==== export var x; \ No newline at end of file From dfada8ec844f4f01877c7dc0c33d900db5b75d63 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 22 Oct 2015 14:24:04 -0700 Subject: [PATCH 15/31] remove es6 check form system module --- src/compiler/emitter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 70ab3606c6c..86ada2b25a7 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2770,7 +2770,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi * we we emit variable statement 'var' should be dropped. */ function isSourceFileLevelDeclarationInSystemJsModule(node: Node, isExported: boolean): boolean { - if (!node || languageVersion >= ScriptTarget.ES6 || !isCurrentFileSystemExternalModule()) { + if (!node || !isCurrentFileSystemExternalModule()) { return false; } From 58d20ae2e350321266acd6fd43adab38a9b4c91b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 22 Oct 2015 14:36:09 -0700 Subject: [PATCH 16/31] accept new baselines --- tests/baselines/reference/systemModule1.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/systemModule1.js b/tests/baselines/reference/systemModule1.js index 573a7ae04c8..8d99e84ae9f 100644 --- a/tests/baselines/reference/systemModule1.js +++ b/tests/baselines/reference/systemModule1.js @@ -8,7 +8,7 @@ System.register([], function(exports_1) { return { setters:[], execute: function() { - x = 1; + exports_1("x", x = 1); } } }); From fc2dca23448c66f6f31aafc46b2e2b7136c2bee5 Mon Sep 17 00:00:00 2001 From: Julian Williams Date: Thu, 22 Oct 2015 18:18:57 -0400 Subject: [PATCH 17/31] Added test. --- tests/cases/compiler/typeAliasDeclareKeyword01.d.ts | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/cases/compiler/typeAliasDeclareKeyword01.d.ts diff --git a/tests/cases/compiler/typeAliasDeclareKeyword01.d.ts b/tests/cases/compiler/typeAliasDeclareKeyword01.d.ts new file mode 100644 index 00000000000..cf2a5061937 --- /dev/null +++ b/tests/cases/compiler/typeAliasDeclareKeyword01.d.ts @@ -0,0 +1,2 @@ +type Foo = number; +declare type Bar = string; \ No newline at end of file From c30ac53c66e164ac1260ddf8a1f54ade497733c5 Mon Sep 17 00:00:00 2001 From: Julian Williams Date: Thu, 22 Oct 2015 20:44:50 -0400 Subject: [PATCH 18/31] Accepted baselines. --- .../reference/typeAliasDeclareKeyword01.d.errors.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/baselines/reference/typeAliasDeclareKeyword01.d.errors.txt diff --git a/tests/baselines/reference/typeAliasDeclareKeyword01.d.errors.txt b/tests/baselines/reference/typeAliasDeclareKeyword01.d.errors.txt new file mode 100644 index 00000000000..000ef77c3f4 --- /dev/null +++ b/tests/baselines/reference/typeAliasDeclareKeyword01.d.errors.txt @@ -0,0 +1,8 @@ +tests/cases/compiler/typeAliasDeclareKeyword01.d.ts(1,1): error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. + + +==== tests/cases/compiler/typeAliasDeclareKeyword01.d.ts (1 errors) ==== + type Foo = number; + ~~~~ +!!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. + declare type Bar = string; \ No newline at end of file From 7c251bc605a34fcd527aeb59a46e15335d34747b Mon Sep 17 00:00:00 2001 From: Brett Mayen Date: Thu, 22 Oct 2015 21:01:24 -0700 Subject: [PATCH 19/31] add normalizePath to to fix slashes --- src/compiler/tsc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 9d79d435a04..976107e540c 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -566,7 +566,7 @@ namespace ts { function writeConfigFile(options: CompilerOptions, fileNames: string[]) { let currentDirectory = sys.getCurrentDirectory(); - let file = combinePaths(currentDirectory, "tsconfig.json"); + let file = normalizePath(combinePaths(currentDirectory, "tsconfig.json")); if (sys.fileExists(file)) { reportDiagnostic(createCompilerDiagnostic(Diagnostics.A_tsconfig_json_file_is_already_defined_at_Colon_0, file)); } From bf1335b0e6a0161b95ecfdeb38cbd6146756e0b4 Mon Sep 17 00:00:00 2001 From: zhengbli Date: Fri, 23 Oct 2015 12:39:16 -0700 Subject: [PATCH 20/31] CR feedback. --- src/server/server.ts | 52 ++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 33 deletions(-) diff --git a/src/server/server.ts b/src/server/server.ts index 5f181511783..26279959ad7 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -155,51 +155,37 @@ namespace ts.server { var logger = createLoggerFromEnv(); - var messagesToWrite: string[] = []; - function addMessage(message: string) { - messagesToWrite.push(message); - // If the current message list has more than 1 messages, that means - // the current writing is not ended yet, so don't start new writeNext - // as it may interfere with ongoing writing sessions. - if (messagesToWrite.length === 1) { - startWrite(); + let pending: string[] = []; + function queueMessage(s: string) { + pending.push(s); + if (pending.length === 1) { + drain(); } } - function startWrite() { - if (messagesToWrite.length === 0) { - return; - } - - let messageToWrite = messagesToWrite[0]; - let buffer = new Buffer(messageToWrite, "utf8"); - write(buffer); + function drain() { + Debug.assert(pending.length > 0); + writeBuffer(new Buffer(pending[0], "utf8"), 0); } - function writeNext() { - if (messagesToWrite.length > 0) { - messagesToWrite = copyListRemovingItem(messagesToWrite[0], messagesToWrite); - } - startWrite(); - } - - function write(buffer: any, offset = 0) { - let toWrite = buffer.length - offset; - fs.write(1, buffer, offset, toWrite, /*position*/undefined, function(err: any, written: number, buffer: any) { - offset += written; + function writeBuffer(buffer: Buffer, offset: number) { + const toWrite = buffer.length - offset; + fs.write(1, buffer, offset, toWrite, undefined, (err, written, buffer) => { if (toWrite > written) { - // there are some content left that still need to be written - write(buffer, offset); + writeBuffer(buffer, offset + written); } else { - // ready to write the next string - writeNext(); + Debug.assert(pending.length > 0); + pending.shift(); + if (pending.length > 0) { + drain(); + } } - }) + }); } // Override sys.write because fs.writeSync is not reliable on Node 4 - ts.sys.write = (s: string) => addMessage(s); + ts.sys.write = (s: string) => queueMessage(s); var ioSession = new IOSession(ts.sys, logger); process.on('uncaughtException', function(err: Error) { From 19a222e7185ad69d16573efba538823409dbd33b Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 23 Oct 2015 13:09:05 -0700 Subject: [PATCH 21/31] addressed PR feedback --- src/compiler/tsc.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index a72b5bb1b06..dd0f9246d05 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -159,6 +159,8 @@ namespace ts { let timerHandleForRecompilation: number; // Handle for 0.25s wait timer to trigger recompilation let timerHandleForDirectoryChanges: number; // Handle for 0.25s wait timer to trigger directory change handler + // This map stores and reuses results of fileExists check that happen inside 'createProgram' + // This allows to save time in module resolution heavy scenarios when existence of the same file might be checked multiple times. let cachedExistingFiles: Map; let hostFileExists: typeof compilerHost.fileExists; @@ -279,7 +281,7 @@ namespace ts { compilerHost.getSourceFile = getSourceFile; hostFileExists = compilerHost.fileExists; - compilerHost.fileExists = fileExists; + compilerHost.fileExists = cachedFileExists; } // reset the cache of existing files @@ -295,7 +297,7 @@ namespace ts { reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes)); } - function fileExists(fileName: string): boolean { + function cachedFileExists(fileName: string): boolean { if (hasProperty(cachedExistingFiles, fileName)) { return cachedExistingFiles[fileName]; } From 7a1004371b949cd6174677a0d64d840d8d30662f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 23 Oct 2015 13:33:55 -0700 Subject: [PATCH 22/31] Add tests and accept baselines --- .../reference/unionTypeCallSignatures.errors.txt | 8 +++++++- tests/baselines/reference/unionTypeCallSignatures.js | 6 ++++++ .../conformance/types/union/unionTypeCallSignatures.ts | 3 +++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/unionTypeCallSignatures.errors.txt b/tests/baselines/reference/unionTypeCallSignatures.errors.txt index ebe38a589ee..bf1de6ff8e8 100644 --- a/tests/baselines/reference/unionTypeCallSignatures.errors.txt +++ b/tests/baselines/reference/unionTypeCallSignatures.errors.txt @@ -28,9 +28,10 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(67,12): error TS2 tests/cases/conformance/types/union/unionTypeCallSignatures.ts(68,12): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(69,12): error TS2346: Supplied parameters do not match any signature of call target. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(70,12): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(73,12): error TS2346: Supplied parameters do not match any signature of call target. -==== tests/cases/conformance/types/union/unionTypeCallSignatures.ts (30 errors) ==== +==== tests/cases/conformance/types/union/unionTypeCallSignatures.ts (31 errors) ==== var numOrDate: number | Date; var strOrBoolean: string | boolean; var strOrNum: string | number; @@ -162,4 +163,9 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(70,12): error TS2 ~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2346: Supplied parameters do not match any signature of call target. + var unionWithRestParameter4: { (...a: string[]): string; } | { (a: string, b: string): number; }; + strOrNum = unionWithRestParameter4("hello"); // error supplied parameters do not match any call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + strOrNum = unionWithRestParameter4("hello", "world"); \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeCallSignatures.js b/tests/baselines/reference/unionTypeCallSignatures.js index fc3dfc8ebbc..103d92fbef3 100644 --- a/tests/baselines/reference/unionTypeCallSignatures.js +++ b/tests/baselines/reference/unionTypeCallSignatures.js @@ -70,6 +70,9 @@ strOrNum = unionWithRestParameter3('hello', 10, 11); // error no call signature strOrNum = unionWithRestParameter3('hello', "hello"); // error no call signature strOrNum = unionWithRestParameter3(); // error no call signature +var unionWithRestParameter4: { (...a: string[]): string; } | { (a: string, b: string): number; }; +strOrNum = unionWithRestParameter4("hello"); // error supplied parameters do not match any call signature +strOrNum = unionWithRestParameter4("hello", "world"); //// [unionTypeCallSignatures.js] @@ -132,3 +135,6 @@ strOrNum = unionWithRestParameter3('hello', 10); // error no call signature strOrNum = unionWithRestParameter3('hello', 10, 11); // error no call signature strOrNum = unionWithRestParameter3('hello', "hello"); // error no call signature strOrNum = unionWithRestParameter3(); // error no call signature +var unionWithRestParameter4; +strOrNum = unionWithRestParameter4("hello"); // error supplied parameters do not match any call signature +strOrNum = unionWithRestParameter4("hello", "world"); diff --git a/tests/cases/conformance/types/union/unionTypeCallSignatures.ts b/tests/cases/conformance/types/union/unionTypeCallSignatures.ts index ca599329743..a25d27d9a29 100644 --- a/tests/cases/conformance/types/union/unionTypeCallSignatures.ts +++ b/tests/cases/conformance/types/union/unionTypeCallSignatures.ts @@ -69,3 +69,6 @@ strOrNum = unionWithRestParameter3('hello', 10, 11); // error no call signature strOrNum = unionWithRestParameter3('hello', "hello"); // error no call signature strOrNum = unionWithRestParameter3(); // error no call signature +var unionWithRestParameter4: { (...a: string[]): string; } | { (a: string, b: string): number; }; +strOrNum = unionWithRestParameter4("hello"); // error supplied parameters do not match any call signature +strOrNum = unionWithRestParameter4("hello", "world"); From ab2994ff8711744d70dade9794b256e71f992910 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 23 Oct 2015 13:34:09 -0700 Subject: [PATCH 23/31] Fix union types of variadic functions The check used `=== len - 1` instead of `>= len - 1` to check whether a parameter index might be pointing to a rest argument. --- src/compiler/checker.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b3fa607b0ea..80fbb0f08b3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5620,11 +5620,10 @@ namespace ts { // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N source = getErasedSignature(source); target = getErasedSignature(target); - let sourceLen = source.parameters.length; let targetLen = target.parameters.length; for (let i = 0; i < targetLen; i++) { - let s = source.hasRestParameter && i === sourceLen - 1 ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]); - let t = target.hasRestParameter && i === targetLen - 1 ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]); + let s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]); + let t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]); let related = compareTypes(s, t); if (!related) { return Ternary.False; @@ -5637,6 +5636,10 @@ namespace ts { return result; } + function isRestParameterIndex(signature: Signature, parameterIndex: number) { + return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1; + } + function isSupertypeOfEach(candidate: Type, types: Type[]): boolean { for (let type of types) { if (candidate !== type && !isTypeSubtypeOf(type, candidate)) return false; @@ -6798,8 +6801,9 @@ namespace ts { } // If last parameter is contextually rest parameter get its type - if (indexOfParameter === (func.parameters.length - 1) && - funcHasRestParameters && contextualSignature.hasRestParameter && func.parameters.length >= contextualSignature.parameters.length) { + if (funcHasRestParameters && + indexOfParameter === (func.parameters.length - 1) && + isRestParameterIndex(contextualSignature, func.parameters.length - 1)) { return getTypeOfSymbol(lastOrUndefined(contextualSignature.parameters)); } } @@ -8390,7 +8394,7 @@ namespace ts { // If spread arguments are present, check that they correspond to a rest parameter. If so, no // further checking is necessary. if (spreadArgIndex >= 0) { - return signature.hasRestParameter && spreadArgIndex >= signature.parameters.length - 1; + return isRestParameterIndex(signature, spreadArgIndex); } // Too many arguments implies incorrect arity. @@ -9381,7 +9385,7 @@ namespace ts { let contextualParameterType = getTypeAtPosition(context, i); assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); } - if (signature.hasRestParameter && context.hasRestParameter && signature.parameters.length >= context.parameters.length) { + if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) { let parameter = lastOrUndefined(signature.parameters); let contextualParameterType = getTypeOfSymbol(lastOrUndefined(context.parameters)); assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType, mapper); From 742c701868dd75d4063745250c87407061e3ea5e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 23 Oct 2015 14:26:45 -0700 Subject: [PATCH 24/31] Use emptyArray instead of [] for no base types. --- src/compiler/checker.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fcdb93b01e0..a2283bc9d7d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2867,7 +2867,7 @@ namespace ts { } function resolveBaseTypesOfClass(type: InterfaceType): void { - type.resolvedBaseTypes = type.resolvedBaseTypes || []; + type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; let baseContructorType = getBaseConstructorTypeOfClass(type); if (!(baseContructorType.flags & TypeFlags.ObjectType)) { return; @@ -2903,11 +2903,16 @@ namespace ts { typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); return; } - type.resolvedBaseTypes.push(baseType); + if (type.resolvedBaseTypes === emptyArray) { + type.resolvedBaseTypes = [baseType]; + } + else { + type.resolvedBaseTypes.push(baseType); + } } function resolveBaseTypesOfInterface(type: InterfaceType): void { - type.resolvedBaseTypes = type.resolvedBaseTypes || []; + type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; for (let declaration of type.symbol.declarations) { if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(declaration)) { for (let node of getInterfaceBaseTypeNodes(declaration)) { @@ -2915,7 +2920,12 @@ namespace ts { if (baseType !== unknownType) { if (getTargetType(baseType).flags & (TypeFlags.Class | TypeFlags.Interface)) { if (type !== baseType && !hasBaseType(baseType, type)) { - type.resolvedBaseTypes.push(baseType); + if (type.resolvedBaseTypes === emptyArray) { + type.resolvedBaseTypes = [baseType]; + } + else { + type.resolvedBaseTypes.push(baseType); + } } else { error(declaration, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); From 368258036698515db4e109e35c9bac6e56825e81 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 23 Oct 2015 16:27:44 -0700 Subject: [PATCH 25/31] First draft of test parallelisation --- Jakefile.js | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Jakefile.js b/Jakefile.js index b025bba4087..0ea82c0019a 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -627,7 +627,46 @@ function deleteTemporaryProjectOutput() { } var testTimeout = 20000; -desc("Runs the tests using the built run.js file. Syntax is jake runtests. Optional parameters 'host=', 'tests=[regex], reporter=[list|spec|json|]', debug=true."); +desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false."); +task("runalltests", ["build-rules", "tests", builtLocalDirectory], function() { + cleanTestDirs(); + var debug = process.env.debug || process.env.d; + tests = process.env.test || process.env.tests || process.env.t; + var light = process.env.light || false; + var testConfigFile = 'test.config'; + if(fs.existsSync(testConfigFile)) { + fs.unlinkSync(testConfigFile); + } + + if(tests || light) { + writeTestConfigFile(tests, light, testConfigFile); + } + + if (tests && tests.toLocaleLowerCase() === "rwc") { + testTimeout = 100000; + } + + colors = process.env.colors || process.env.color + colors = colors ? ' --no-colors ' : ' --colors '; + reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter'; + // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally + // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer + var subsets = ['compiler', 'conformance', 'project', 'fourslash'] + var res = subsets.map(function (sub) { return "^" + sub + ".*$"; }); + res.push("^(?!" + subsets.join("|") + ").*$"); + res.forEach(function (re) { + tests = ' -g "' + re + '"'; + // pass different name.global.js files to mocha? for exmaple, each name.global.js would set a different option for the harness runner + var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; + console.log(cmd); + exec(cmd, function() { + deleteTemporaryProjectOutput(); + complete(); + }); + }) +}, {async: true}); + +desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false."); task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { cleanTestDirs(); var debug = process.env.debug || process.env.d; From a0939d962be86c9c6e3c0a7df0440824d2c8d8f0 Mon Sep 17 00:00:00 2001 From: Julian Williams Date: Fri, 23 Oct 2015 22:43:11 -0400 Subject: [PATCH 26/31] Added TypeAliasDeclaration to exceptions for required top level declare modifier --- src/compiler/checker.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 663825f1e84..c7317908273 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15917,6 +15917,7 @@ namespace ts { // export_opt AmbientDeclaration // if (node.kind === SyntaxKind.InterfaceDeclaration || + node.kind === SyntaxKind.TypeAliasDeclaration || node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration || node.kind === SyntaxKind.ExportDeclaration || From 5613ba860f773bce9ed40d2172caf4a615369724 Mon Sep 17 00:00:00 2001 From: Julian Williams Date: Sat, 24 Oct 2015 13:43:11 -0400 Subject: [PATCH 27/31] accepted baselines --- .../reference/typeAliasDeclareKeyword01.d.errors.txt | 8 -------- .../reference/typeAliasDeclareKeyword01.d.symbols | 7 +++++++ .../baselines/reference/typeAliasDeclareKeyword01.d.types | 7 +++++++ 3 files changed, 14 insertions(+), 8 deletions(-) delete mode 100644 tests/baselines/reference/typeAliasDeclareKeyword01.d.errors.txt create mode 100644 tests/baselines/reference/typeAliasDeclareKeyword01.d.symbols create mode 100644 tests/baselines/reference/typeAliasDeclareKeyword01.d.types diff --git a/tests/baselines/reference/typeAliasDeclareKeyword01.d.errors.txt b/tests/baselines/reference/typeAliasDeclareKeyword01.d.errors.txt deleted file mode 100644 index 000ef77c3f4..00000000000 --- a/tests/baselines/reference/typeAliasDeclareKeyword01.d.errors.txt +++ /dev/null @@ -1,8 +0,0 @@ -tests/cases/compiler/typeAliasDeclareKeyword01.d.ts(1,1): error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. - - -==== tests/cases/compiler/typeAliasDeclareKeyword01.d.ts (1 errors) ==== - type Foo = number; - ~~~~ -!!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file. - declare type Bar = string; \ No newline at end of file diff --git a/tests/baselines/reference/typeAliasDeclareKeyword01.d.symbols b/tests/baselines/reference/typeAliasDeclareKeyword01.d.symbols new file mode 100644 index 00000000000..86c1ae8f40c --- /dev/null +++ b/tests/baselines/reference/typeAliasDeclareKeyword01.d.symbols @@ -0,0 +1,7 @@ +=== tests/cases/compiler/typeAliasDeclareKeyword01.d.ts === +type Foo = number; +>Foo : Symbol(Foo, Decl(typeAliasDeclareKeyword01.d.ts, 0, 0)) + +declare type Bar = string; +>Bar : Symbol(Bar, Decl(typeAliasDeclareKeyword01.d.ts, 0, 18)) + diff --git a/tests/baselines/reference/typeAliasDeclareKeyword01.d.types b/tests/baselines/reference/typeAliasDeclareKeyword01.d.types new file mode 100644 index 00000000000..588fdd9012c --- /dev/null +++ b/tests/baselines/reference/typeAliasDeclareKeyword01.d.types @@ -0,0 +1,7 @@ +=== tests/cases/compiler/typeAliasDeclareKeyword01.d.ts === +type Foo = number; +>Foo : number + +declare type Bar = string; +>Bar : string + From 1d6f5c6781509715430eac337067273e5cae90c0 Mon Sep 17 00:00:00 2001 From: Julian Williams Date: Sat, 24 Oct 2015 22:21:34 -0400 Subject: [PATCH 28/31] Added grammar change to the comments. --- src/compiler/checker.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c7317908273..9766926c3d0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15912,10 +15912,12 @@ namespace ts { // DeclarationElement: // ExportAssignment // export_opt InterfaceDeclaration + // export_opt TypeAliasDeclaration // export_opt ImportDeclaration // export_opt ExternalImportDeclaration // export_opt AmbientDeclaration // + // TODO: The spec needs to be amended to reflect this grammar. if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration || node.kind === SyntaxKind.ImportDeclaration || From e2bfbd54f52ff16df9d5fbe1ae83ea7e94c6fb2c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 26 Oct 2015 08:06:19 -0700 Subject: [PATCH 29/31] Rename, default to 'min' and fix Projects case 1. Rename to runtests-parallel 2. Change default reporter to 'min', which reduces interleaved/interfering output. 3. Change 'projects' to 'Projects' --- Jakefile.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index 0ea82c0019a..c4bdc51308a 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -628,7 +628,7 @@ function deleteTemporaryProjectOutput() { var testTimeout = 20000; desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false."); -task("runalltests", ["build-rules", "tests", builtLocalDirectory], function() { +task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function() { cleanTestDirs(); var debug = process.env.debug || process.env.d; tests = process.env.test || process.env.tests || process.env.t; @@ -648,10 +648,10 @@ task("runalltests", ["build-rules", "tests", builtLocalDirectory], function() { colors = process.env.colors || process.env.color colors = colors ? ' --no-colors ' : ' --colors '; - reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter'; + reporter = process.env.reporter || process.env.r || 'min'; // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer - var subsets = ['compiler', 'conformance', 'project', 'fourslash'] + var subsets = ['compiler', 'conformance', 'Projects', 'fourslash'] var res = subsets.map(function (sub) { return "^" + sub + ".*$"; }); res.push("^(?!" + subsets.join("|") + ").*$"); res.forEach(function (re) { From 3127684351167b1f1125330948cde13c44720e27 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Mon, 26 Oct 2015 10:25:01 -0700 Subject: [PATCH 30/31] Make runtests and runtests-parallel share code Also some minor cleanup. --- Jakefile.js | 81 ++++++++++++++++++++++------------------------------- 1 file changed, 34 insertions(+), 47 deletions(-) diff --git a/Jakefile.js b/Jakefile.js index c4bdc51308a..dae99085bef 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -626,9 +626,7 @@ function deleteTemporaryProjectOutput() { } } -var testTimeout = 20000; -desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false."); -task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function() { +function runConsoleTests(defaultReporter, defaultSubsets, postLint) { cleanTestDirs(); var debug = process.env.debug || process.env.d; tests = process.env.test || process.env.tests || process.env.t; @@ -638,7 +636,7 @@ task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], functio fs.unlinkSync(testConfigFile); } - if(tests || light) { + if (tests || light) { writeTestConfigFile(tests, light, testConfigFile); } @@ -648,59 +646,48 @@ task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], functio colors = process.env.colors || process.env.color colors = colors ? ' --no-colors ' : ' --colors '; - reporter = process.env.reporter || process.env.r || 'min'; + reporter = process.env.reporter || process.env.r || defaultReporter; + // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer - var subsets = ['compiler', 'conformance', 'Projects', 'fourslash'] - var res = subsets.map(function (sub) { return "^" + sub + ".*$"; }); - res.push("^(?!" + subsets.join("|") + ").*$"); - res.forEach(function (re) { - tests = ' -g "' + re + '"'; - // pass different name.global.js files to mocha? for exmaple, each name.global.js would set a different option for the harness runner + var subsetRegexes; + if(defaultSubsets.length === 0) { + subsetRegexes = [tests] + } + else { + var subsets = tests ? tests.split("|") : defaultSubsets; + subsetRegexes = subsets.map(function (sub) { return "^" + sub + ".*$"; }); + subsetRegexes.push("^(?!" + subsets.join("|") + ").*$"); + } + subsetRegexes.forEach(function (subsetRegex) { + tests = subsetRegex ? ' -g "' + subsetRegex + '"' : ''; var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; console.log(cmd); - exec(cmd, function() { + exec(cmd, function () { deleteTemporaryProjectOutput(); - complete(); + if (postLint) { + var lint = jake.Task['lint']; + lint.addListener('complete', function () { + complete(); + }); + lint.invoke(); + } + else { + complete(); + } }); - }) + }); +} + +var testTimeout = 20000; +desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true."); +task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function() { + runConsoleTests('min', ['compiler', 'conformance', 'Projects', 'fourslash']); }, {async: true}); desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false."); task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { - cleanTestDirs(); - var debug = process.env.debug || process.env.d; - tests = process.env.test || process.env.tests || process.env.t; - var light = process.env.light || false; - var testConfigFile = 'test.config'; - if(fs.existsSync(testConfigFile)) { - fs.unlinkSync(testConfigFile); - } - - if(tests || light) { - writeTestConfigFile(tests, light, testConfigFile); - } - - if (tests && tests.toLocaleLowerCase() === "rwc") { - testTimeout = 100000; - } - - colors = process.env.colors || process.env.color - colors = colors ? ' --no-colors ' : ' --colors '; - tests = tests ? ' -g ' + tests : ''; - reporter = process.env.reporter || process.env.r || 'mocha-fivemat-progress-reporter'; - // timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally - // default timeout is 2sec which really should be enough, but maybe we just need a small amount longer - var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + ' -t ' + testTimeout + ' ' + run; - console.log(cmd); - exec(cmd, function() { - deleteTemporaryProjectOutput(); - var lint = jake.Task['lint']; - lint.addListener('complete', function () { - complete(); - }); - lint.invoke(); - }); + runConsoleTests('mocha-fivemat-progress-reporter', [], /*postLint*/ true); }, {async: true}); desc("Generates code coverage data via instanbul"); From 751a8ea148bec3b5d4dce6f7d11c4d78249ba435 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Mon, 26 Oct 2015 10:43:55 -0700 Subject: [PATCH 31/31] allow other files except .d.ts as external library packages --- src/compiler/diagnosticMessages.json | 4 ---- src/compiler/program.ts | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 188cf23f76c..139e078e2ab 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1712,10 +1712,6 @@ "category": "Error", "code": 2654 }, - "Exported external package typings can only be in '.d.ts' files. Please contact the package author to update the package definition.": { - "category": "Error", - "code": 2655 - }, "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition.": { "category": "Error", "code": 2656 diff --git a/src/compiler/program.ts b/src/compiler/program.ts index d76e7585d15..d39a4c7912f 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -863,10 +863,6 @@ namespace ts { let start = getTokenPosOfNode(file.imports[i], file); fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition, importedFile.fileName)); } - else if (!fileExtensionIs(importedFile.fileName, ".d.ts")) { - let start = getTokenPosOfNode(file.imports[i], file); - fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_can_only_be_in_d_ts_files_Please_contact_the_package_author_to_update_the_package_definition)); - } else if (importedFile.referencedFiles.length) { let firstRef = importedFile.referencedFiles[0]; fileProcessingDiagnostics.add(createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition));