From eba4d3673931dc748cdf5b0e4633646b23a0deb9 Mon Sep 17 00:00:00 2001 From: kingwl <805037171@163.com> Date: Thu, 14 Dec 2017 09:26:05 +0800 Subject: [PATCH 001/229] error if import empty object form module not existed --- src/compiler/checker.ts | 5 ++++- .../reference/importEmptyFromModuleNotExisted.errors.txt | 8 ++++++++ .../reference/importEmptyFromModuleNotExisted.js | 7 +++++++ .../reference/importEmptyFromModuleNotExisted.symbols | 4 ++++ .../reference/importEmptyFromModuleNotExisted.types | 4 ++++ .../es6/modules/importEmptyFromModuleNotExisted.ts | 1 + 6 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/importEmptyFromModuleNotExisted.errors.txt create mode 100644 tests/baselines/reference/importEmptyFromModuleNotExisted.js create mode 100644 tests/baselines/reference/importEmptyFromModuleNotExisted.symbols create mode 100644 tests/baselines/reference/importEmptyFromModuleNotExisted.types create mode 100644 tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bb7f8d013fc..0c44bd928a7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23852,7 +23852,10 @@ namespace ts { checkImportBinding(importClause.namedBindings); } else { - forEach(importClause.namedBindings.elements, checkImportBinding); + const moduleExisted = resolveExternalModuleName(node, node.moduleSpecifier); + if (moduleExisted) { + forEach(importClause.namedBindings.elements, checkImportBinding); + } } } } diff --git a/tests/baselines/reference/importEmptyFromModuleNotExisted.errors.txt b/tests/baselines/reference/importEmptyFromModuleNotExisted.errors.txt new file mode 100644 index 00000000000..99ccd49c489 --- /dev/null +++ b/tests/baselines/reference/importEmptyFromModuleNotExisted.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts(1,16): error TS2307: Cannot find module 'module-not-existed'. + + +==== tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts (1 errors) ==== + import {} from 'module-not-existed' + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'module-not-existed'. + \ No newline at end of file diff --git a/tests/baselines/reference/importEmptyFromModuleNotExisted.js b/tests/baselines/reference/importEmptyFromModuleNotExisted.js new file mode 100644 index 00000000000..aa08db2e99e --- /dev/null +++ b/tests/baselines/reference/importEmptyFromModuleNotExisted.js @@ -0,0 +1,7 @@ +//// [importEmptyFromModuleNotExisted.ts] +import {} from 'module-not-existed' + + +//// [importEmptyFromModuleNotExisted.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/importEmptyFromModuleNotExisted.symbols b/tests/baselines/reference/importEmptyFromModuleNotExisted.symbols new file mode 100644 index 00000000000..ea0425ff26c --- /dev/null +++ b/tests/baselines/reference/importEmptyFromModuleNotExisted.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts === +import {} from 'module-not-existed' +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/importEmptyFromModuleNotExisted.types b/tests/baselines/reference/importEmptyFromModuleNotExisted.types new file mode 100644 index 00000000000..ea0425ff26c --- /dev/null +++ b/tests/baselines/reference/importEmptyFromModuleNotExisted.types @@ -0,0 +1,4 @@ +=== tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts === +import {} from 'module-not-existed' +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts b/tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts new file mode 100644 index 00000000000..36bca3e9619 --- /dev/null +++ b/tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts @@ -0,0 +1 @@ +import {} from 'module-not-existed' From 4c4f0e8e65f5aebc28957e2ebc6921ba99e1feea Mon Sep 17 00:00:00 2001 From: falsandtru Date: Wed, 21 Mar 2018 17:18:42 +0900 Subject: [PATCH 002/229] Fix Promise interfaces --- src/lib/es2015.promise.d.ts | 2 +- src/lib/es5.d.ts | 4 +++- .../reference/defaultExportInAwaitExpression01.types | 6 +++--- .../reference/defaultExportInAwaitExpression02.types | 6 +++--- tests/baselines/reference/inferenceLimit.types | 12 ++++++------ ...dularizeLibrary_NoErrorDuplicateLibOptions1.types | 4 ++-- ...dularizeLibrary_NoErrorDuplicateLibOptions2.types | 4 ++-- .../modularizeLibrary_TargetES5UsingES6Lib.types | 4 ++-- tests/baselines/reference/usePromiseFinally.types | 4 ++-- 9 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/lib/es2015.promise.d.ts b/src/lib/es2015.promise.d.ts index ab33531191f..af43abe63d6 100644 --- a/src/lib/es2015.promise.d.ts +++ b/src/lib/es2015.promise.d.ts @@ -10,7 +10,7 @@ interface PromiseConstructor { * a resolve callback used resolve the promise with a value or the result of another promise, * and a reject callback used to reject the promise with a provided reason or error. */ - new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; + new (executor: (resolve: [T] extends [void] ? (value?: T | PromiseLike) => void : (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 1f352cd6f39..c213677feac 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1273,7 +1273,9 @@ declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) declare type MethodDecorator = (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void; declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void; -declare type PromiseConstructorLike = new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void) => PromiseLike; +interface PromiseConstructorLike { + new (executor: (resolve: [T] extends [void] ? (value?: T | PromiseLike) => void : (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void): PromiseLike; +} interface PromiseLike { /** diff --git a/tests/baselines/reference/defaultExportInAwaitExpression01.types b/tests/baselines/reference/defaultExportInAwaitExpression01.types index 1f7de76b90e..a68e9b88fa2 100644 --- a/tests/baselines/reference/defaultExportInAwaitExpression01.types +++ b/tests/baselines/reference/defaultExportInAwaitExpression01.types @@ -3,11 +3,11 @@ const x = new Promise( ( resolve, reject ) => { resolve( {} ); } ); >x : Promise<{}> >new Promise( ( resolve, reject ) => { resolve( {} ); } ) : Promise<{}> >Promise : PromiseConstructor ->( resolve, reject ) => { resolve( {} ); } : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value?: {} | PromiseLike<{}>) => void +>( resolve, reject ) => { resolve( {} ); } : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void >resolve( {} ) : void ->resolve : (value?: {} | PromiseLike<{}>) => void +>resolve : (value: {} | PromiseLike<{}>) => void >{} : {} export default x; diff --git a/tests/baselines/reference/defaultExportInAwaitExpression02.types b/tests/baselines/reference/defaultExportInAwaitExpression02.types index 1f7de76b90e..a68e9b88fa2 100644 --- a/tests/baselines/reference/defaultExportInAwaitExpression02.types +++ b/tests/baselines/reference/defaultExportInAwaitExpression02.types @@ -3,11 +3,11 @@ const x = new Promise( ( resolve, reject ) => { resolve( {} ); } ); >x : Promise<{}> >new Promise( ( resolve, reject ) => { resolve( {} ); } ) : Promise<{}> >Promise : PromiseConstructor ->( resolve, reject ) => { resolve( {} ); } : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value?: {} | PromiseLike<{}>) => void +>( resolve, reject ) => { resolve( {} ); } : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void >resolve( {} ) : void ->resolve : (value?: {} | PromiseLike<{}>) => void +>resolve : (value: {} | PromiseLike<{}>) => void >{} : {} export default x; diff --git a/tests/baselines/reference/inferenceLimit.types b/tests/baselines/reference/inferenceLimit.types index 4a398932232..16e030241c2 100644 --- a/tests/baselines/reference/inferenceLimit.types +++ b/tests/baselines/reference/inferenceLimit.types @@ -21,8 +21,8 @@ export class BrokenClass { >Array : T[] >MyModule : any >MyModel : MyModule.MyModel ->(resolve, reject) => { let result: Array = []; let populateItems = (order) => { return new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }); }; return Promise.all(result.map(populateItems)) .then((orders: Array) => { resolve(orders); }); } : (resolve: (value?: MyModule.MyModel[] | PromiseLike) => void, reject: (reason?: any) => void) => Promise ->resolve : (value?: MyModule.MyModel[] | PromiseLike) => void +>(resolve, reject) => { let result: Array = []; let populateItems = (order) => { return new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }); }; return Promise.all(result.map(populateItems)) .then((orders: Array) => { resolve(orders); }); } : (resolve: (value: MyModule.MyModel[] | PromiseLike) => void, reject: (reason?: any) => void) => Promise +>resolve : (value: MyModule.MyModel[] | PromiseLike) => void >reject : (reason?: any) => void let result: Array = []; @@ -40,8 +40,8 @@ export class BrokenClass { return new Promise((resolve, reject) => { >new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }) : Promise<{}> >Promise : PromiseConstructor ->(resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); } : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value?: {} | PromiseLike<{}>) => void +>(resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); } : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void this.doStuff(order.id) @@ -69,7 +69,7 @@ export class BrokenClass { resolve(order); >resolve(order) : void ->resolve : (value?: {} | PromiseLike<{}>) => void +>resolve : (value: {} | PromiseLike<{}>) => void >order : any }); @@ -99,7 +99,7 @@ export class BrokenClass { resolve(orders); >resolve(orders) : void ->resolve : (value?: MyModule.MyModel[] | PromiseLike) => void +>resolve : (value: MyModule.MyModel[] | PromiseLike) => void >orders : MyModule.MyModel[] }); diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types index 78e6a6bc3f5..bda310b20e4 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types @@ -138,8 +138,8 @@ async function out() { return new Promise(function (resolve, reject) {}); >new Promise(function (resolve, reject) {}) : Promise<{}> >Promise : PromiseConstructor ->function (resolve, reject) {} : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value?: {} | PromiseLike<{}>) => void +>function (resolve, reject) {} : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void } diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types index 4aabae824ee..8d05cc40ce4 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types @@ -138,8 +138,8 @@ async function out() { return new Promise(function (resolve, reject) {}); >new Promise(function (resolve, reject) {}) : Promise<{}> >Promise : PromiseConstructor ->function (resolve, reject) {} : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value?: {} | PromiseLike<{}>) => void +>function (resolve, reject) {} : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void } diff --git a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types index 2782c70ebd9..9334b118d71 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types +++ b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types @@ -138,8 +138,8 @@ async function out() { return new Promise(function (resolve, reject) {}); >new Promise(function (resolve, reject) {}) : Promise<{}> >Promise : PromiseConstructor ->function (resolve, reject) {} : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value?: {} | PromiseLike<{}>) => void +>function (resolve, reject) {} : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void } diff --git a/tests/baselines/reference/usePromiseFinally.types b/tests/baselines/reference/usePromiseFinally.types index 80534c75610..2dd2d82da79 100644 --- a/tests/baselines/reference/usePromiseFinally.types +++ b/tests/baselines/reference/usePromiseFinally.types @@ -5,8 +5,8 @@ let promise1 = new Promise(function(resolve, reject) {}) >new Promise(function(resolve, reject) {}) .finally : (onfinally?: () => void) => Promise<{}> >new Promise(function(resolve, reject) {}) : Promise<{}> >Promise : PromiseConstructor ->function(resolve, reject) {} : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value?: {} | PromiseLike<{}>) => void +>function(resolve, reject) {} : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void .finally(function() {}); From a8d6a45cd645314cce86ab758f902ee70be44fd4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 5 Apr 2018 06:25:34 -0700 Subject: [PATCH 003/229] Move nameType from SymbolLinks to TransientSymbol --- src/compiler/checker.ts | 50 ++++++++++++++++++++--------------------- src/compiler/types.ts | 2 +- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c60f9c23029..8b692471eba 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3793,10 +3793,13 @@ namespace ts { return "(Anonymous function)"; } } - if ((symbol as TransientSymbol).nameType && (symbol as TransientSymbol).nameType.flags & TypeFlags.StringLiteral) { - const stringValue = ((symbol as TransientSymbol).nameType as StringLiteralType).value; - if (!isIdentifierText(stringValue, compilerOptions.target)) { - return `"${escapeString(stringValue, CharacterCodes.doubleQuote)}"`; + if (isTransientSymbol(symbol)) { + const nameType = (symbol).nameType; + if (nameType && nameType.flags & TypeFlags.StringLiteral && !isIdentifierText((nameType).value, compilerOptions.target)) { + return `"${escapeString((nameType).value, CharacterCodes.doubleQuote)}"`; + } + if (nameType && nameType.flags & TypeFlags.UniqueESSymbol) { + return `[${getNameOfSymbolAsWritten((nameType).symbol, context)}]`; } } return symbolName(symbol); @@ -5539,7 +5542,7 @@ namespace ts { * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { + function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: UnderscoreEscapedMap, decl: LateBoundDeclaration) { Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { @@ -5568,13 +5571,7 @@ namespace ts { error(decl.name || decl, Diagnostics.Duplicate_declaration_0, name); lateSymbol = createSymbol(SymbolFlags.None, memberName, CheckFlags.Late); } - - const symbolLinks = getSymbolLinks(lateSymbol); - if (!symbolLinks.nameType) { - // Retain link to name type so that it can be reused later - symbolLinks.nameType = type; - } - + lateSymbol.nameType = type; addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags); if (lateSymbol.parent) { Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one"); @@ -5602,7 +5599,7 @@ namespace ts { links[resolutionKind] = earlySymbols || emptySymbols; // fill in any as-yet-unresolved late-bound members. - const lateSymbols = createSymbolTable(); + const lateSymbols = createMap() as UnderscoreEscapedMap; for (const decl of symbol.declarations) { const members = getMembersOfDeclaration(decl); if (members) { @@ -8116,18 +8113,14 @@ namespace ts { } function getLiteralTypeFromPropertyName(prop: Symbol) { - const links = getSymbolLinks(getLateBoundSymbol(prop)); - if (!links.nameType) { - if (links.target && links.target !== unknownSymbol && links.target !== resolvingSymbol && links.target.escapedName === prop.escapedName) { - links.nameType = getLiteralTypeFromPropertyName(links.target); - } - else { - links.nameType = getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || isKnownSymbol(prop) ? - neverType : - getLiteralType(symbolName(prop)); - } + if (getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || isKnownSymbol(prop)) { + return neverType; } - return links.nameType; + const symbol = getLateBoundSymbol(prop); + if (isTransientSymbol(symbol) && symbol.nameType) { + return symbol.nameType; + } + return getLiteralType(symbolName(prop)); } function getLiteralTypeFromPropertyNames(type: Type) { @@ -9061,8 +9054,13 @@ namespace ts { if (symbol.valueDeclaration) { result.valueDeclaration = symbol.valueDeclaration; } - if ((symbol as TransientSymbol).isRestParameter) { - result.isRestParameter = (symbol as TransientSymbol).isRestParameter; + if (isTransientSymbol(symbol)) { + if (symbol.isRestParameter) { + result.isRestParameter = symbol.isRestParameter; + } + if (symbol.nameType) { + result.nameType = symbol.nameType; + } } return result; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4edfc29a2a1..768cb196cca 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3399,7 +3399,6 @@ namespace ts { enumKind?: EnumKind; // Enum declaration classification originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol` lateSymbol?: Symbol; // Late-bound symbol for a computed property - nameType?: Type; // Type associate with a late-bound or mapped type property symbol's name } /* @internal */ @@ -3429,6 +3428,7 @@ namespace ts { export interface TransientSymbol extends Symbol, SymbolLinks { checkFlags: CheckFlags; isRestParameter?: boolean; + nameType?: Type; // Type associated with a late-bound symbol } /* @internal */ From 39bb93fb1a94f14235ca9f495c9713dad591393b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 5 Apr 2018 16:00:06 -0700 Subject: [PATCH 004/229] Move nameType to base Symbol, generate nameType properties where missing --- src/compiler/checker.ts | 83 ++++++++++++++++++----------------------- src/compiler/types.ts | 10 ++--- 2 files changed, 42 insertions(+), 51 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8b692471eba..ff3d53229ba 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3793,9 +3793,9 @@ namespace ts { return "(Anonymous function)"; } } - if (isTransientSymbol(symbol)) { - const nameType = (symbol).nameType; - if (nameType && nameType.flags & TypeFlags.StringLiteral && !isIdentifierText((nameType).value, compilerOptions.target)) { + const nameType = symbol.nameType; + if (nameType) { + if (nameType.flags & TypeFlags.StringLiteral && !isIdentifierText((nameType).value, compilerOptions.target)) { return `"${escapeString((nameType).value, CharacterCodes.doubleQuote)}"`; } if (nameType && nameType.flags & TypeFlags.UniqueESSymbol) { @@ -6003,6 +6003,7 @@ namespace ts { const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0); const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ReverseMappedSymbol; inferredProp.declarations = prop.declarations; + inferredProp.nameType = prop.nameType; inferredProp.propertyType = getTypeOfSymbol(prop); inferredProp.mappedType = type.mappedType; members.set(prop.escapedName, inferredProp); @@ -6027,8 +6028,8 @@ namespace ts { if (constraintDeclaration.kind === SyntaxKind.TypeOperator && (constraintDeclaration).operator === SyntaxKind.KeyOfKeyword) { // We have a { [P in keyof T]: X } - for (const propertySymbol of getPropertiesOfType(modifiersType)) { - addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol); + for (const prop of getPropertiesOfType(modifiersType)) { + addMemberForKeyType(getLiteralTypeFromPropertyName(prop), undefined, prop); } if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) { addMemberForKeyType(stringType); @@ -6044,14 +6045,7 @@ namespace ts { } setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined); - function addMemberForKeyType(t: Type, propertySymbolOrIndex?: Symbol | number) { - let propertySymbol: Symbol; - // forEachType delegates to forEach, which calls with a numeric second argument - // the type system currently doesn't catch this incompatibility, so we annotate - // the function ourselves to indicate the runtime behavior and deal with it here - if (typeof propertySymbolOrIndex === "object") { - propertySymbol = propertySymbolOrIndex; - } + function addMemberForKeyType(t: Type, _index?: number, origin?: Symbol) { // Create a mapper from T to the current iteration type constituent. Then, if the // mapped type is itself an instantiated type, combine the iteration mapper with the // instantiation mapper. @@ -6060,7 +6054,7 @@ namespace ts { // If the current iteration type constituent is a string literal type, create a property. // Otherwise, for type string create a string index signature. if (t.flags & TypeFlags.StringLiteral) { - const propName = getLateBoundNameFromType(t as LiteralType | UniqueESSymbolType); + const propName = getLateBoundNameFromType(t as LiteralType); const modifiersProp = getPropertyOfType(modifiersType, propName); const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional || !(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional); @@ -6073,9 +6067,9 @@ namespace ts { prop.type = strictNullChecks && isOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) : strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : propType; - if (propertySymbol) { - prop.syntheticOrigin = propertySymbol; - prop.declarations = propertySymbol.declarations; + if (origin) { + prop.syntheticOrigin = origin; + prop.declarations = origin.declarations; } prop.nameType = t; members.set(propName, prop); @@ -6529,6 +6523,7 @@ namespace ts { } propTypes.push(type); } + // !!! const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags); result.containingType = containingType; result.declarations = declarations; @@ -8116,11 +8111,7 @@ namespace ts { if (getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || isKnownSymbol(prop)) { return neverType; } - const symbol = getLateBoundSymbol(prop); - if (isTransientSymbol(symbol) && symbol.nameType) { - return symbol.nameType; - } - return getLiteralType(symbolName(prop)); + return getLateBoundSymbol(prop).nameType || getLiteralType(symbolName(prop)); } function getLiteralTypeFromPropertyNames(type: Type) { @@ -8681,6 +8672,7 @@ namespace ts { result.leftSpread = leftProp; result.rightSpread = rightProp; result.declarations = declarations; + result.nameType = leftProp.nameType; members.set(leftProp.escapedName, result); } } @@ -8709,6 +8701,7 @@ namespace ts { const result = createSymbol(flags, prop.escapedName); result.type = getTypeOfSymbol(prop); result.declarations = prop.declarations; + result.nameType = prop.nameType; result.syntheticOrigin = prop; return result; } @@ -9054,13 +9047,13 @@ namespace ts { if (symbol.valueDeclaration) { result.valueDeclaration = symbol.valueDeclaration; } + if (symbol.nameType) { + result.nameType = symbol.nameType; + } if (isTransientSymbol(symbol)) { if (symbol.isRestParameter) { result.isRestParameter = symbol.isRestParameter; } - if (symbol.nameType) { - result.nameType = symbol.nameType; - } } return result; } @@ -10772,8 +10765,7 @@ namespace ts { continue; } // Skip over symbol-named members - const nameType = getLiteralTypeFromPropertyName(prop); - if (nameType !== undefined && !(isRelatedTo(nameType, stringType) || isRelatedTo(nameType, numberType))) { + if (prop.nameType && prop.nameType.flags & TypeFlags.UniqueESSymbol) { continue; } if (kind === IndexKind.String || isNumericLiteralName(prop.escapedName)) { @@ -11376,6 +11368,9 @@ namespace ts { if (source.valueDeclaration) { symbol.valueDeclaration = source.valueDeclaration; } + if (source.nameType) { + symbol.nameType = source.nameType; + } return symbol; } @@ -11418,7 +11413,7 @@ namespace ts { } function createWideningContext(parent: WideningContext, propertyName: __String, siblings: Type[]): WideningContext { - return { parent, propertyName, siblings, resolvedPropertyNames: undefined }; + return { parent, propertyName, siblings, resolvedProperties: undefined }; } function getSiblingsOfContext(context: WideningContext): Type[] { @@ -11439,19 +11434,19 @@ namespace ts { return context.siblings; } - function getPropertyNamesOfContext(context: WideningContext): __String[] { - if (!context.resolvedPropertyNames) { - const names = createMap() as UnderscoreEscapedMap; + function getPropertiesOfContext(context: WideningContext): Symbol[] { + if (!context.resolvedProperties) { + const names = createMap() as UnderscoreEscapedMap; for (const t of getSiblingsOfContext(context)) { if (isObjectLiteralType(t) && !(getObjectFlags(t) & ObjectFlags.ContainsSpread)) { for (const prop of getPropertiesOfType(t)) { - names.set(prop.escapedName, true); + names.set(prop.escapedName, prop); } } } - context.resolvedPropertyNames = arrayFrom(names.keys()); + context.resolvedProperties = arrayFrom(names.values()); } - return context.resolvedPropertyNames; + return context.resolvedProperties; } function getWidenedProperty(prop: Symbol, context: WideningContext): Symbol { @@ -11461,18 +11456,14 @@ namespace ts { return widened === original ? prop : createSymbolWithType(prop, widened); } - function getUndefinedProperty(name: __String) { - const cached = undefinedProperties.get(name); + function getUndefinedProperty(prop: Symbol) { + const cached = undefinedProperties.get(prop.escapedName); if (cached) { return cached; } - const result = createSymbol(SymbolFlags.Property | SymbolFlags.Optional, name); - result.type = undefinedType; - const associatedKeyType = getLiteralType(unescapeLeadingUnderscores(name)); - if (associatedKeyType.flags & TypeFlags.StringLiteral) { - result.nameType = associatedKeyType; - } - undefinedProperties.set(name, result); + const result = createSymbolWithType(prop, undefinedType); + result.flags |= SymbolFlags.Optional; + undefinedProperties.set(prop.escapedName, result); return result; } @@ -11484,9 +11475,9 @@ namespace ts { members.set(prop.escapedName, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop, context) : prop); } if (context) { - for (const name of getPropertyNamesOfContext(context)) { - if (!members.has(name)) { - members.set(name, getUndefinedProperty(name)); + for (const prop of getPropertiesOfContext(context)) { + if (!members.has(prop.escapedName)) { + members.set(prop.escapedName, getUndefinedProperty(prop)); } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 768cb196cca..bd526921c2a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3361,6 +3361,7 @@ namespace ts { members?: SymbolTable; // Class, interface or object literal instance members exports?: SymbolTable; // Module exports globalExports?: SymbolTable; // Conditional global UMD exports + nameType?: Type; // Type associated with a late-bound symbol /* @internal */ id?: number; // Unique id (used to look up SymbolLinks) /* @internal */ mergeId?: number; // Merge id (used to look up merged symbol) /* @internal */ parent?: Symbol; // Parent symbol @@ -3428,7 +3429,6 @@ namespace ts { export interface TransientSymbol extends Symbol, SymbolLinks { checkFlags: CheckFlags; isRestParameter?: boolean; - nameType?: Type; // Type associated with a late-bound symbol } /* @internal */ @@ -4029,10 +4029,10 @@ namespace ts { /* @internal */ export interface WideningContext { - parent?: WideningContext; // Parent context - propertyName?: __String; // Name of property in parent - siblings?: Type[]; // Types of siblings - resolvedPropertyNames?: __String[]; // Property names occurring in sibling object literals + parent?: WideningContext; // Parent context + propertyName?: __String; // Name of property in parent + siblings?: Type[]; // Types of siblings + resolvedProperties?: Symbol[]; // Properties occurring in sibling object literals } /* @internal */ From fc85ba9e6a372b1f256e663380457b097c7b9c9d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 6 Apr 2018 09:52:00 -0700 Subject: [PATCH 005/229] Limit getLiteralTypeFromPropertyName to only return string-like types --- src/compiler/checker.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ff3d53229ba..216854e9b6e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8108,10 +8108,16 @@ namespace ts { } function getLiteralTypeFromPropertyName(prop: Symbol) { - if (getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier || isKnownSymbol(prop)) { - return neverType; + if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) { + const nameType = getLateBoundSymbol(prop).nameType; + if (nameType) { + return nameType.flags & TypeFlags.StringLiteral ? nameType : neverType; + } + if (!isKnownSymbol(prop)) { + return getLiteralType(symbolName(prop)); + } } - return getLateBoundSymbol(prop).nameType || getLiteralType(symbolName(prop)); + return neverType; } function getLiteralTypeFromPropertyNames(type: Type) { From ccf20d3f6735d84c2a6fd5409247b43d2c40a53d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 6 Apr 2018 09:52:10 -0700 Subject: [PATCH 006/229] Accept new baselines --- .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + ...ndConstraintTypeChecksCorrectly.errors.txt | 29 +++++++++++++++++ .../objectLiteralNormalization.symbols | 32 +++++++++---------- 4 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 tests/baselines/reference/lateBoundConstraintTypeChecksCorrectly.errors.txt diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index aca4e956181..a90af4eaf96 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2015,6 +2015,7 @@ declare namespace ts { members?: SymbolTable; exports?: SymbolTable; globalExports?: SymbolTable; + nameType?: Type; } enum InternalSymbolName { Call = "__call", diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index aa77372db45..3847c7c54a5 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2015,6 +2015,7 @@ declare namespace ts { members?: SymbolTable; exports?: SymbolTable; globalExports?: SymbolTable; + nameType?: Type; } enum InternalSymbolName { Call = "__call", diff --git a/tests/baselines/reference/lateBoundConstraintTypeChecksCorrectly.errors.txt b/tests/baselines/reference/lateBoundConstraintTypeChecksCorrectly.errors.txt new file mode 100644 index 00000000000..d9d573e0ab9 --- /dev/null +++ b/tests/baselines/reference/lateBoundConstraintTypeChecksCorrectly.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts(17,16): error TS2536: Type 'unique symbol' cannot be used to index type 'T'. +tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts(18,17): error TS2536: Type 'unique symbol' cannot be used to index type 'T'. + + +==== tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts (2 errors) ==== + declare const fooProp: unique symbol; + declare const barProp: unique symbol; + + type BothProps = typeof fooProp | typeof barProp; + + export interface Foo { + [fooProp]: T; + [barProp]: string; + } + + function f>(x: T) { + const abc = x[fooProp]; // expected: 'T[typeof fooProp]' + + /** + * Expected: no error + */ + const def: T[typeof fooProp] = x[fooProp]; + ~~~~~~~~~~~~~~~~~ +!!! error TS2536: Type 'unique symbol' cannot be used to index type 'T'. + const def2: T[typeof barProp] = x[barProp]; + ~~~~~~~~~~~~~~~~~ +!!! error TS2536: Type 'unique symbol' cannot be used to index type 'T'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralNormalization.symbols b/tests/baselines/reference/objectLiteralNormalization.symbols index 69882d81f76..416065ee5c9 100644 --- a/tests/baselines/reference/objectLiteralNormalization.symbols +++ b/tests/baselines/reference/objectLiteralNormalization.symbols @@ -15,14 +15,14 @@ a1.a; // number >a : Symbol(a, Decl(objectLiteralNormalization.ts, 1, 11), Decl(objectLiteralNormalization.ts, 1, 21), Decl(objectLiteralNormalization.ts, 1, 39)) a1.b; // string | undefined ->a1.b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 27), Decl(objectLiteralNormalization.ts, 1, 45)) +>a1.b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 45), Decl(objectLiteralNormalization.ts, 1, 27), Decl(objectLiteralNormalization.ts, 1, 45)) >a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3)) ->b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 27), Decl(objectLiteralNormalization.ts, 1, 45)) +>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 45), Decl(objectLiteralNormalization.ts, 1, 27), Decl(objectLiteralNormalization.ts, 1, 45)) a1.c; // boolean | undefined ->a1.c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53)) +>a1.c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53), Decl(objectLiteralNormalization.ts, 1, 53)) >a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3)) ->c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53)) +>c : Symbol(c, Decl(objectLiteralNormalization.ts, 1, 53), Decl(objectLiteralNormalization.ts, 1, 53)) a1 = { a: 1 }; >a1 : Symbol(a1, Decl(objectLiteralNormalization.ts, 1, 3)) @@ -48,14 +48,14 @@ let a2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0]; >a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 27)) a2.a; // string | number | undefined ->a2.a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27)) +>a2.a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27), Decl(objectLiteralNormalization.ts, 10, 27)) >a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3)) ->a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27)) +>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 11), Decl(objectLiteralNormalization.ts, 10, 27), Decl(objectLiteralNormalization.ts, 10, 27)) a2.b; // number | undefined ->a2.b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17)) +>a2.b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17), Decl(objectLiteralNormalization.ts, 1, 45)) >a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3)) ->b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17)) +>b : Symbol(b, Decl(objectLiteralNormalization.ts, 10, 17), Decl(objectLiteralNormalization.ts, 1, 45)) a2 = { a: 10, b: 20 }; >a2 : Symbol(a2, Decl(objectLiteralNormalization.ts, 10, 3)) @@ -144,32 +144,32 @@ d1.pos; >pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) d1.pos.x; ->d1.pos.x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29)) +>d1.pos.x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29), Decl(objectLiteralNormalization.ts, 33, 29)) >d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) >d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3)) >pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) ->x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29)) +>x : Symbol(x, Decl(objectLiteralNormalization.ts, 33, 29), Decl(objectLiteralNormalization.ts, 33, 29)) d1.pos.y; ->d1.pos.y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35)) +>d1.pos.y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35), Decl(objectLiteralNormalization.ts, 33, 35)) >d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) >d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3)) >pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) ->y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35)) +>y : Symbol(y, Decl(objectLiteralNormalization.ts, 33, 35), Decl(objectLiteralNormalization.ts, 33, 35)) d1.pos.a; ->d1.pos.a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73)) +>d1.pos.a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 27), Decl(objectLiteralNormalization.ts, 33, 73)) >d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) >d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3)) >pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) ->a : Symbol(a, Decl(objectLiteralNormalization.ts, 33, 73)) +>a : Symbol(a, Decl(objectLiteralNormalization.ts, 10, 27), Decl(objectLiteralNormalization.ts, 33, 73)) d1.pos.b; ->d1.pos.b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86)) +>d1.pos.b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 45), Decl(objectLiteralNormalization.ts, 33, 86)) >d1.pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) >d1 : Symbol(d1, Decl(objectLiteralNormalization.ts, 33, 3)) >pos : Symbol(pos, Decl(objectLiteralNormalization.ts, 33, 22), Decl(objectLiteralNormalization.ts, 33, 58)) ->b : Symbol(b, Decl(objectLiteralNormalization.ts, 33, 86)) +>b : Symbol(b, Decl(objectLiteralNormalization.ts, 1, 45), Decl(objectLiteralNormalization.ts, 33, 86)) declare function f(...items: T[]): T; >f : Symbol(f, Decl(objectLiteralNormalization.ts, 39, 9)) From ff20f38405e084bfec6a31fae6b60e39d04cc8c0 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 9 Apr 2018 07:45:13 -1000 Subject: [PATCH 007/229] Add support for numbers and symbols in keyof (but keep it disabled) --- src/compiler/checker.ts | 74 +++++++++++++++++++++++----- src/compiler/commandLineParser.ts | 6 +++ src/compiler/diagnosticMessages.json | 4 ++ src/compiler/types.ts | 3 +- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 216854e9b6e..fb0e279df37 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -72,6 +72,7 @@ namespace ts { const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization"); const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny"); const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis"); + const keyofStringsOnly = true; // !!compilerOptions.keyofStringsOnly; const emitResolver = createResolver(); const nodeBuilder = createNodeBuilder(); @@ -346,6 +347,9 @@ namespace ts { const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); + const stringNumberType = getUnionType([stringType, numberType]); + const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]); + const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType; const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); @@ -420,6 +424,7 @@ namespace ts { let deferredGlobalAsyncIteratorType: GenericType; let deferredGlobalAsyncIterableIteratorType: GenericType; let deferredGlobalTemplateStringsArrayType: ObjectType; + let deferredGlobalExtractSymbol: Symbol; let deferredNodes: Node[]; let deferredUnusedIdentifierNodes: Node[]; @@ -4207,7 +4212,7 @@ namespace ts { // right hand expression is of a type parameter type. if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForInStatement) { const indexType = getIndexType(checkNonNullExpression(declaration.parent.parent.expression)); - return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? indexType : stringType; + return indexType.flags & (TypeFlags.TypeParameter | TypeFlags.Index) ? getExtractStringType(indexType) : stringType; } if (isVariableDeclaration(declaration) && declaration.parent.parent.kind === SyntaxKind.ForOfStatement) { @@ -6015,6 +6020,7 @@ namespace ts { function resolveMappedTypeMembers(type: MappedType) { const members: SymbolTable = createSymbolTable(); let stringIndexInfo: IndexInfo; + let numberIndexInfo: IndexInfo; // Resolve upfront such that recursive references see an empty object type. setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined); // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type, @@ -6025,15 +6031,19 @@ namespace ts { const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' const templateModifiers = getMappedTypeModifiers(type); const constraintDeclaration = type.declaration.typeParameter.constraint; + const include = keyofStringsOnly ? TypeFlags.StringLiteral : TypeFlags.StringOrNumberLiteralOrUnique; if (constraintDeclaration.kind === SyntaxKind.TypeOperator && (constraintDeclaration).operator === SyntaxKind.KeyOfKeyword) { // We have a { [P in keyof T]: X } for (const prop of getPropertiesOfType(modifiersType)) { - addMemberForKeyType(getLiteralTypeFromPropertyName(prop), undefined, prop); + addMemberForKeyType(getLiteralTypeFromPropertyName(prop, include), undefined, prop); } if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) { addMemberForKeyType(stringType); } + if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, IndexKind.Number)) { + addMemberForKeyType(numberType); + } } else { // First, if the constraint type is a type parameter, obtain the base constraint. Then, @@ -6043,7 +6053,7 @@ namespace ts { const iterationType = keyType.flags & TypeFlags.Index ? getIndexType(getApparentType((keyType).type)) : keyType; forEachType(iterationType, addMemberForKeyType); } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined); + setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo); function addMemberForKeyType(t: Type, _index?: number, origin?: Symbol) { // Create a mapper from T to the current iteration type constituent. Then, if the @@ -6077,6 +6087,9 @@ namespace ts { else if (t.flags & (TypeFlags.Any | TypeFlags.String)) { stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); } + else if (t.flags & TypeFlags.Number) { + numberIndexInfo = createIndexInfo(propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); + } } } @@ -6468,6 +6481,7 @@ namespace ts { t.flags & TypeFlags.BooleanLike ? globalBooleanType : t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : t.flags & TypeFlags.NonPrimitive ? emptyObjectType : + t.flags & TypeFlags.Index ? keyofConstraintType : t; } @@ -7665,6 +7679,10 @@ namespace ts { return symbol && getTypeOfGlobalSymbol(symbol, arity); } + function getGlobalExtractSymbol(): Symbol { + return deferredGlobalExtractSymbol || (deferredGlobalExtractSymbol = getGlobalSymbol("Extract" as __String, SymbolFlags.TypeAlias, Diagnostics.Cannot_find_global_type_0)); + } + /** * Instantiates a global type that is generic with some element type, and returns that instantiation. */ @@ -8107,11 +8125,11 @@ namespace ts { return type.resolvedIndexType; } - function getLiteralTypeFromPropertyName(prop: Symbol) { + function getLiteralTypeFromPropertyName(prop: Symbol, include: TypeFlags) { if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) { const nameType = getLateBoundSymbol(prop).nameType; if (nameType) { - return nameType.flags & TypeFlags.StringLiteral ? nameType : neverType; + return nameType.flags & include ? nameType : neverType; } if (!isKnownSymbol(prop)) { return getLiteralType(symbolName(prop)); @@ -8120,8 +8138,25 @@ namespace ts { return neverType; } - function getLiteralTypeFromPropertyNames(type: Type) { - return getUnionType(map(getPropertiesOfType(type), getLiteralTypeFromPropertyName)); + function getLiteralTypeFromPropertyNames(type: Type, include: TypeFlags) { + return getUnionType(map(getPropertiesOfType(type), t => getLiteralTypeFromPropertyName(t, include))); + } + + function getNonEnumNumberIndexInfo(type: Type) { + const numberIndexInfo = getIndexInfoOfType(type, IndexKind.Number); + return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined; + } + + function getStringOnlyIndexType(type: Type) { + return type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : + getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral); + } + + function getStringNumberSymbolIndexType(type: Type) { + return type.flags & TypeFlags.Any ? stringNumberSymbolType : + getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringNumberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : + getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : + getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol); } function getIndexType(type: Type): Type { @@ -8129,12 +8164,19 @@ namespace ts { maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : - type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : - getLiteralTypeFromPropertyNames(type); + keyofStringsOnly ? getStringOnlyIndexType(type) : getStringNumberSymbolIndexType(type); + } + + function getExtractStringType(type: Type) { + if (keyofStringsOnly) { + return type; + } + const extractTypeAlias = getGlobalExtractSymbol(); + return extractTypeAlias ? getTypeAliasInstantiation(extractTypeAlias, [type, stringType]) : stringType; } function getIndexTypeOrString(type: Type): Type { - const indexType = getIndexType(type); + const indexType = getExtractStringType(getIndexType(type)); return indexType.flags & TypeFlags.Never ? stringType : indexType; } @@ -8632,7 +8674,7 @@ namespace ts { if (right.flags & TypeFlags.Union) { return mapType(right, t => getSpreadType(left, t, symbol, typeFlags, objectFlags)); } - if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive)) { + if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) { return left; } @@ -10379,6 +10421,12 @@ namespace ts { } } } + else if (source.flags & TypeFlags.Index) { + if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) { + errorInfo = saveErrorInfo; + return result; + } + } else if (source.flags & TypeFlags.Conditional) { if (target.flags & TypeFlags.Conditional) { // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if @@ -15190,7 +15238,7 @@ namespace ts { // type, and any union of these types (like string | number). if (links.resolvedType.flags & TypeFlags.Nullable || !isTypeAssignableToKind(links.resolvedType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike) && - !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) { + !isTypeAssignableTo(links.resolvedType, stringNumberSymbolType)) { error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } else { @@ -20841,7 +20889,7 @@ namespace ts { const type = getTypeFromMappedTypeNode(node); const constraintType = getConstraintTypeFromMappedType(type); - checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); + checkTypeAssignableTo(constraintType, keyofConstraintType, node.typeParameter.constraint); } function checkTypeOperator(node: TypeOperatorNode) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index f386c701dd7..86d4ffa1c3f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -678,6 +678,12 @@ namespace ts { category: Diagnostics.Advanced_Options, description: Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types, }, + { + name: "keyofStringsOnly", + type: "boolean", + category: Diagnostics.Advanced_Options, + description: Diagnostics.Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols, + }, { // A list of plugins to load in the language service name: "plugins", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0bf047c770d..756247b7459 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3516,6 +3516,10 @@ "category": "Error", "code": 6192 }, + "Resolve 'keyof' to string valued property names only (no numbers or symbols).": { + "category": "Message", + "code": 6193 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index bd526921c2a..2e6ac6f3190 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3596,7 +3596,7 @@ namespace ts { Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive, /* @internal */ Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol, - StringLike = String | StringLiteral | Index, + StringLike = String | StringLiteral, NumberLike = Number | NumberLiteral | Enum, BooleanLike = Boolean | BooleanLiteral, EnumLike = Enum | EnumLiteral, @@ -4144,6 +4144,7 @@ namespace ts { inlineSources?: boolean; isolatedModules?: boolean; jsx?: JsxEmit; + keyofStringsOnly?: boolean; lib?: string[]; /*@internal*/listEmittedFiles?: boolean; /*@internal*/listFiles?: boolean; From 68ce69a351ad9100b7bd44f3791908bb7e09ff13 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 9 Apr 2018 07:45:55 -1000 Subject: [PATCH 008/229] Move 'PropertyKey' from es2015.core.d.ts to es5.d.ts --- src/lib/es2015.core.d.ts | 35 ----------------------------------- src/lib/es5.d.ts | 12 +++++++----- 2 files changed, 7 insertions(+), 40 deletions(-) diff --git a/src/lib/es2015.core.d.ts b/src/lib/es2015.core.d.ts index 68be040c29d..cfb300c784d 100644 --- a/src/lib/es2015.core.d.ts +++ b/src/lib/es2015.core.d.ts @@ -1,5 +1,3 @@ -declare type PropertyKey = string | number | symbol; - interface Array { /** * Returns the value of the first element in the array where predicate is true, and undefined @@ -258,20 +256,6 @@ interface NumberConstructor { parseInt(string: string, radix?: number): number; } -interface Object { - /** - * Determines whether an object has a property with the specified name. - * @param v A property name. - */ - hasOwnProperty(v: PropertyKey): boolean; - - /** - * Determines whether a specified property is enumerable. - * @param v A property name. - */ - propertyIsEnumerable(v: PropertyKey): boolean; -} - interface ObjectConstructor { /** * Copy the values of all of the enumerable own properties from one or more source objects to a @@ -327,25 +311,6 @@ interface ObjectConstructor { * @param proto The value of the new prototype or null. */ setPrototypeOf(o: any, proto: object | null): any; - - /** - * Gets the own property descriptor of the specified object. - * An own property descriptor is one that is defined directly on the object and is not - * inherited from the object's prototype. - * @param o Object that contains the property. - * @param p Name of the property. - */ - getOwnPropertyDescriptor(o: any, propertyKey: PropertyKey): PropertyDescriptor | undefined; - - /** - * Adds a property to an object, or modifies attributes of an existing property. - * @param o Object on which to add or modify the property. This can be a native JavaScript - * object (that is, a user-defined object or a built in object) or a DOM object. - * @param p The property name. - * @param attributes Descriptor for the property. It can be for a data property or an accessor - * property. - */ - defineProperty(o: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): any; } interface ReadonlyArray { diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 1f352cd6f39..9d38f3c2c7c 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -74,6 +74,8 @@ declare function escape(string: string): string; */ declare function unescape(string: string): string; +declare type PropertyKey = string | number | symbol; + interface PropertyDescriptor { configurable?: boolean; enumerable?: boolean; @@ -104,7 +106,7 @@ interface Object { * Determines whether an object has a property with the specified name. * @param v A property name. */ - hasOwnProperty(v: string): boolean; + hasOwnProperty(v: PropertyKey): boolean; /** * Determines whether an object exists in another object's prototype chain. @@ -116,7 +118,7 @@ interface Object { * Determines whether a specified property is enumerable. * @param v A property name. */ - propertyIsEnumerable(v: string): boolean; + propertyIsEnumerable(v: PropertyKey): boolean; } interface ObjectConstructor { @@ -139,7 +141,7 @@ interface ObjectConstructor { * @param o Object that contains the property. * @param p Name of the property. */ - getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor | undefined; + getOwnPropertyDescriptor(o: any, p: PropertyKey): PropertyDescriptor | undefined; /** * Returns the names of the own properties of an object. The own properties of an object are those that are defined directly @@ -167,7 +169,7 @@ interface ObjectConstructor { * @param p The property name. * @param attributes Descriptor for the property. It can be for a data property or an accessor property. */ - defineProperty(o: any, p: string, attributes: PropertyDescriptor & ThisType): any; + defineProperty(o: any, p: PropertyKey, attributes: PropertyDescriptor & ThisType): any; /** * Adds one or more properties to an object, and/or modifies attributes of existing properties. @@ -1341,7 +1343,7 @@ type Pick = { /** * Construct a type with a set of properties K of type T */ -type Record = { +type Record = { [P in K]: T; }; From 2c021955608af3394807706b0d20d388cad2ee7b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 9 Apr 2018 07:48:13 -1000 Subject: [PATCH 009/229] Accept new baselines --- .../reference/api/tsserverlibrary.d.ts | 3 +- tests/baselines/reference/api/typescript.d.ts | 3 +- .../classAppearsToHaveMembersOfObject.types | 4 +- .../complexRecursiveCollections.symbols | 8 +- .../reference/conditionalTypes1.errors.txt | 76 +++++--- .../reference/conditionalTypes2.errors.txt | 2 + .../controlFlowPropertyDeclarations.types | 4 +- ...coratorOnClassMethodParameter1.es6.symbols | 2 +- .../decoratorsOnComputedProperties.symbols | 2 +- .../decoratorsOnComputedProperties.types | 170 +++++++++--------- .../excessPropertyCheckWithEmptyObject.types | 4 +- .../reference/fixSignatureCaching.types | 16 +- .../reference/getterSetterNonAccessor.types | 4 +- .../reference/indexerConstraints2.types | 6 +- .../keyofAndIndexedAccessErrors.errors.txt | 6 + .../library_ObjectPrototypeProperties.types | 8 +- .../mappedTypeRelationships.errors.txt | 8 + ...singES6ArrayWithOnlyES6ArrayLib.errors.txt | 2 + ...orFromUsingES6FeaturesWithOnlyES5Lib.types | 4 +- ...ibrary_NoErrorDuplicateLibOptions1.symbols | 4 +- ...eLibrary_NoErrorDuplicateLibOptions1.types | 4 +- ...ibrary_NoErrorDuplicateLibOptions2.symbols | 4 +- ...eLibrary_NoErrorDuplicateLibOptions2.types | 4 +- ...larizeLibrary_TargetES5UsingES6Lib.symbols | 4 +- ...dularizeLibrary_TargetES5UsingES6Lib.types | 4 +- ...larizeLibrary_TargetES6UsingES6Lib.symbols | 4 +- ...dularizeLibrary_TargetES6UsingES6Lib.types | 4 +- ...Library_UsingES5LibAndES6FeatureLibs.types | 6 +- .../reference/neverUnionIntersection.types | 2 +- .../reference/numberPropertyAccess.types | 6 +- .../reference/objectLitGetterSetter.types | 4 +- ...peHidingMembersOfExtendedObject.errors.txt | 8 +- ...tringIndexerHidingObjectIndexer.errors.txt | 8 +- .../parserUsingConstructorAsIdentifier.types | 4 +- tests/baselines/reference/parserharness.types | 4 +- .../baselines/reference/propertyAccess.types | 6 +- .../reference/staticInstanceResolution2.types | 8 +- .../reference/stringPropertyAccess.types | 6 +- tests/baselines/reference/symbolType1.symbols | 2 +- .../typePredicateStructuralMatch.types | 8 +- .../reference/unspecializedConstraints.types | 10 +- .../useObjectValuesAndEntries3.symbols | 4 +- .../useObjectValuesAndEntries4.symbols | 4 +- 43 files changed, 251 insertions(+), 203 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a90af4eaf96..2be63b973a5 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2095,7 +2095,7 @@ declare namespace ts { Unit = 13536, StringOrNumberLiteral = 96, PossiblyFalsy = 14574, - StringLike = 524322, + StringLike = 34, NumberLike = 84, BooleanLike = 136, EnumLike = 272, @@ -2332,6 +2332,7 @@ declare namespace ts { inlineSources?: boolean; isolatedModules?: boolean; jsx?: JsxEmit; + keyofStringsOnly?: boolean; lib?: string[]; locale?: string; mapRoot?: string; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3847c7c54a5..0b1b4f43511 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2095,7 +2095,7 @@ declare namespace ts { Unit = 13536, StringOrNumberLiteral = 96, PossiblyFalsy = 14574, - StringLike = 524322, + StringLike = 34, NumberLike = 84, BooleanLike = 136, EnumLike = 272, @@ -2332,6 +2332,7 @@ declare namespace ts { inlineSources?: boolean; isolatedModules?: boolean; jsx?: JsxEmit; + keyofStringsOnly?: boolean; lib?: string[]; locale?: string; mapRoot?: string; diff --git a/tests/baselines/reference/classAppearsToHaveMembersOfObject.types b/tests/baselines/reference/classAppearsToHaveMembersOfObject.types index 9c87fa18ecd..44aeedacba2 100644 --- a/tests/baselines/reference/classAppearsToHaveMembersOfObject.types +++ b/tests/baselines/reference/classAppearsToHaveMembersOfObject.types @@ -17,9 +17,9 @@ var r = c.toString(); var r2 = c.hasOwnProperty(''); >r2 : boolean >c.hasOwnProperty('') : boolean ->c.hasOwnProperty : (v: string) => boolean +>c.hasOwnProperty : (v: string | number | symbol) => boolean >c : C ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >'' : "" var o: Object = c; diff --git a/tests/baselines/reference/complexRecursiveCollections.symbols b/tests/baselines/reference/complexRecursiveCollections.symbols index 4f1a675edaf..4c49735f01d 100644 --- a/tests/baselines/reference/complexRecursiveCollections.symbols +++ b/tests/baselines/reference/complexRecursiveCollections.symbols @@ -1689,7 +1689,7 @@ declare module Immutable { export interface Class { >Class : Symbol(Class, Decl(immutable.ts, 214, 70)) >T : Symbol(T, Decl(immutable.ts, 215, 27)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) (values?: Partial | Iterable<[string, any]>): Instance & Readonly; >values : Symbol(values, Decl(immutable.ts, 216, 7)) @@ -1714,7 +1714,7 @@ declare module Immutable { export interface Instance { >Instance : Symbol(Instance, Decl(immutable.ts, 218, 5)) >T : Symbol(T, Decl(immutable.ts, 219, 30)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) readonly size: number; >size : Symbol(Instance.size, Decl(immutable.ts, 219, 49)) @@ -2005,7 +2005,7 @@ declare module Immutable { toJS(): Object; >toJS : Symbol(Keyed.toJS, Decl(immutable.ts, 269, 76)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) toJSON(): { [key: string]: V }; >toJSON : Symbol(Keyed.toJSON, Decl(immutable.ts, 270, 21)) @@ -2594,7 +2594,7 @@ declare module Immutable { toJS(): Object; >toJS : Symbol(Keyed.toJS, Decl(immutable.ts, 340, 59)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) toJSON(): { [key: string]: V }; >toJSON : Symbol(Keyed.toJSON, Decl(immutable.ts, 341, 21)) diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index 9599cc1bcba..5d1f72c14a0 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -20,22 +20,32 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(106,5): error TS2 Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'keyof T' is not assignable to type 'never'. + Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'never'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(108,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'keyof T' is not assignable to type 'never'. + Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(115,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. @@ -43,8 +53,12 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(115,5): error TS2 Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'keyof T' is not assignable to type 'never'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(116,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(117,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. @@ -207,11 +221,15 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. !!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. !!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. z = x; z = y; // Error ~ @@ -219,11 +237,14 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. !!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. !!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. } function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { @@ -232,7 +253,10 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS y = x; // Error ~ !!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. y = z; // Error ~ !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. @@ -242,10 +266,14 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. !!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. !!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. z = x; // Error ~ !!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. z = y; // Error ~ !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt index 0e7844babc6..41adb72f62d 100644 --- a/tests/baselines/reference/conditionalTypes2.errors.txt +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -6,6 +6,7 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(24,5): error TS23 Types of property 'foo' are incompatible. Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'. Type 'keyof B' is not assignable to type 'keyof A'. + Type 'string' is not assignable to type 'keyof A'. tests/cases/conformance/types/conditional/conditionalTypes2.ts(25,5): error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. Types of property 'foo' are incompatible. Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'. @@ -60,6 +61,7 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2 !!! error TS2322: Types of property 'foo' are incompatible. !!! error TS2322: Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'. !!! error TS2322: Type 'keyof B' is not assignable to type 'keyof A'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof A'. b = a; // Error ~ !!! error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. diff --git a/tests/baselines/reference/controlFlowPropertyDeclarations.types b/tests/baselines/reference/controlFlowPropertyDeclarations.types index 286124ca346..0e698b72608 100644 --- a/tests/baselines/reference/controlFlowPropertyDeclarations.types +++ b/tests/baselines/reference/controlFlowPropertyDeclarations.types @@ -371,11 +371,11 @@ export class StyleParser { if (!this.styles.hasOwnProperty(key)) { >!this.styles.hasOwnProperty(key) : boolean >this.styles.hasOwnProperty(key) : boolean ->this.styles.hasOwnProperty : (v: string) => boolean +>this.styles.hasOwnProperty : (v: string | number | symbol) => boolean >this.styles : {} >this : this >styles : {} ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >key : string } } diff --git a/tests/baselines/reference/decoratorOnClassMethodParameter1.es6.symbols b/tests/baselines/reference/decoratorOnClassMethodParameter1.es6.symbols index aee56f5a4f8..e33f0e8f7b9 100644 --- a/tests/baselines/reference/decoratorOnClassMethodParameter1.es6.symbols +++ b/tests/baselines/reference/decoratorOnClassMethodParameter1.es6.symbols @@ -2,7 +2,7 @@ declare function dec(target: Object, propertyKey: string | symbol, parameterIndex: number): void; >dec : Symbol(dec, Decl(decoratorOnClassMethodParameter1.es6.ts, 0, 0)) >target : Symbol(target, Decl(decoratorOnClassMethodParameter1.es6.ts, 0, 21)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >propertyKey : Symbol(propertyKey, Decl(decoratorOnClassMethodParameter1.es6.ts, 0, 36)) >parameterIndex : Symbol(parameterIndex, Decl(decoratorOnClassMethodParameter1.es6.ts, 0, 66)) diff --git a/tests/baselines/reference/decoratorsOnComputedProperties.symbols b/tests/baselines/reference/decoratorsOnComputedProperties.symbols index 65652b4524e..dc069f22c56 100644 --- a/tests/baselines/reference/decoratorsOnComputedProperties.symbols +++ b/tests/baselines/reference/decoratorsOnComputedProperties.symbols @@ -3,7 +3,7 @@ function x(o: object, k: PropertyKey) { } >x : Symbol(x, Decl(decoratorsOnComputedProperties.ts, 0, 0)) >o : Symbol(o, Decl(decoratorsOnComputedProperties.ts, 0, 11)) >k : Symbol(k, Decl(decoratorsOnComputedProperties.ts, 0, 21)) ->PropertyKey : Symbol(PropertyKey, Decl(lib.es2015.core.d.ts, --, --)) +>PropertyKey : Symbol(PropertyKey, Decl(lib.es5.d.ts, --, --)) let i = 0; >i : Symbol(i, Decl(decoratorsOnComputedProperties.ts, 1, 3)) diff --git a/tests/baselines/reference/decoratorsOnComputedProperties.types b/tests/baselines/reference/decoratorsOnComputedProperties.types index 24ed343c298..efbf9c5d263 100644 --- a/tests/baselines/reference/decoratorsOnComputedProperties.types +++ b/tests/baselines/reference/decoratorsOnComputedProperties.types @@ -1,9 +1,9 @@ === tests/cases/compiler/decoratorsOnComputedProperties.ts === function x(o: object, k: PropertyKey) { } ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >o : object ->k : PropertyKey ->PropertyKey : PropertyKey +>k : string | number | symbol +>PropertyKey : string | number | symbol let i = 0; >i : number @@ -32,25 +32,25 @@ class A { >A : A @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -85,13 +85,13 @@ class A { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @@ -102,12 +102,12 @@ class A { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -119,25 +119,25 @@ void class B { >B : typeof B @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -172,13 +172,13 @@ void class B { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @@ -189,12 +189,12 @@ void class B { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -205,25 +205,25 @@ class C { >C : C @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -258,13 +258,13 @@ class C { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @@ -275,12 +275,12 @@ class C { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -298,25 +298,25 @@ void class D { >D : typeof D @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -351,13 +351,13 @@ void class D { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @@ -368,12 +368,12 @@ void class D { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -390,25 +390,25 @@ class E { >E : E @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -443,13 +443,13 @@ class E { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @@ -466,12 +466,12 @@ class E { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -483,25 +483,25 @@ void class F { >F : typeof F @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -536,13 +536,13 @@ void class F { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @@ -559,12 +559,12 @@ void class F { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -575,25 +575,25 @@ class G { >G : G @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -628,13 +628,13 @@ class G { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @@ -651,7 +651,7 @@ class G { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @@ -662,7 +662,7 @@ class G { >"method2" : "method2" @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -674,25 +674,25 @@ void class H { >H : typeof H @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -727,13 +727,13 @@ void class H { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @@ -750,7 +750,7 @@ void class H { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @@ -761,7 +761,7 @@ void class H { >"method2" : "method2" @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -772,25 +772,25 @@ class I { >I : I @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -825,20 +825,20 @@ class I { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string >null : null @x ["some" + "method"]() {} ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["some" + "method"] : () => void >"some" + "method" : string >"some" : "some" @@ -849,7 +849,7 @@ class I { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @@ -860,7 +860,7 @@ class I { >"method2" : "method2" @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null @@ -872,25 +872,25 @@ void class J { >J : typeof J @x ["property"]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property"] : any >"property" : "property" @x [Symbol.toStringTag]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.toStringTag] : any >Symbol.toStringTag : symbol >Symbol : SymbolConstructor >toStringTag : symbol @x ["property2"]: any = 2; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["property2"] : any >"property2" : "property2" >2 : 2 @x [Symbol.iterator]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[Symbol.iterator] : any >Symbol.iterator : symbol >Symbol : SymbolConstructor @@ -925,20 +925,20 @@ void class J { >foo : () => string @x [foo()]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string @x [foo()]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[foo()] : any >foo() : string >foo : () => string >null : null @x ["some" + "method"]() {} ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >["some" + "method"] : () => void >"some" + "method" : string >"some" : "some" @@ -949,7 +949,7 @@ void class J { >fieldNameA : string @x [fieldNameB]: any; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameB] : any >fieldNameB : string @@ -960,7 +960,7 @@ void class J { >"method2" : "method2" @x [fieldNameC]: any = null; ->x : (o: object, k: PropertyKey) => void +>x : (o: object, k: string | number | symbol) => void >[fieldNameC] : any >fieldNameC : string >null : null diff --git a/tests/baselines/reference/excessPropertyCheckWithEmptyObject.types b/tests/baselines/reference/excessPropertyCheckWithEmptyObject.types index ecf15c74da5..9748820aacd 100644 --- a/tests/baselines/reference/excessPropertyCheckWithEmptyObject.types +++ b/tests/baselines/reference/excessPropertyCheckWithEmptyObject.types @@ -4,9 +4,9 @@ // Excess property error expected here Object.defineProperty(window, "prop", { value: "v1.0.0", readonly: false }); >Object.defineProperty(window, "prop", { value: "v1.0.0", readonly: false }) : any ->Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any +>Object.defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any >Object : ObjectConstructor ->defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any +>defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any >window : any >"prop" : "prop" >{ value: "v1.0.0", readonly: false } : { value: string; readonly: boolean; } diff --git a/tests/baselines/reference/fixSignatureCaching.types b/tests/baselines/reference/fixSignatureCaching.types index c3f4dbc1522..8b66a3f7b95 100644 --- a/tests/baselines/reference/fixSignatureCaching.types +++ b/tests/baselines/reference/fixSignatureCaching.types @@ -1068,12 +1068,12 @@ define(function () { }; var hasOwnProp = Object.prototype.hasOwnProperty, ->hasOwnProp : (v: string) => boolean ->Object.prototype.hasOwnProperty : (v: string) => boolean +>hasOwnProp : (v: string | number | symbol) => boolean +>Object.prototype.hasOwnProperty : (v: string | number | symbol) => boolean >Object.prototype : Object >Object : ObjectConstructor >prototype : Object ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean isArray; >isArray : any @@ -1249,7 +1249,7 @@ define(function () { if (hasOwnProp.call(object, key)) { >hasOwnProp.call(object, key) : any >hasOwnProp.call : (this: Function, thisArg: any, ...argArray: any[]) => any ->hasOwnProp : (v: string) => boolean +>hasOwnProp : (v: string | number | symbol) => boolean >call : (this: Function, thisArg: any, ...argArray: any[]) => any >object : any >key : string @@ -1296,7 +1296,7 @@ define(function () { if (hasOwnProp.call(mobileDetectRules.props, key)) { >hasOwnProp.call(mobileDetectRules.props, key) : any >hasOwnProp.call : (this: Function, thisArg: any, ...argArray: any[]) => any ->hasOwnProp : (v: string) => boolean +>hasOwnProp : (v: string | number | symbol) => boolean >call : (this: Function, thisArg: any, ...argArray: any[]) => any >mobileDetectRules.props : any >mobileDetectRules : any @@ -1487,7 +1487,7 @@ define(function () { if (hasOwnProp.call(rules, key)) { >hasOwnProp.call(rules, key) : any >hasOwnProp.call : (this: Function, thisArg: any, ...argArray: any[]) => any ->hasOwnProp : (v: string) => boolean +>hasOwnProp : (v: string | number | symbol) => boolean >call : (this: Function, thisArg: any, ...argArray: any[]) => any >rules : any >key : string @@ -1538,7 +1538,7 @@ define(function () { if (hasOwnProp.call(rules, key)) { >hasOwnProp.call(rules, key) : any >hasOwnProp.call : (this: Function, thisArg: any, ...argArray: any[]) => any ->hasOwnProp : (v: string) => boolean +>hasOwnProp : (v: string | number | symbol) => boolean >call : (this: Function, thisArg: any, ...argArray: any[]) => any >rules : any >key : string @@ -1598,7 +1598,7 @@ define(function () { if (hasOwnProp.call(props, propertyName)) { >hasOwnProp.call(props, propertyName) : any >hasOwnProp.call : (this: Function, thisArg: any, ...argArray: any[]) => any ->hasOwnProp : (v: string) => boolean +>hasOwnProp : (v: string | number | symbol) => boolean >call : (this: Function, thisArg: any, ...argArray: any[]) => any >props : any >propertyName : any diff --git a/tests/baselines/reference/getterSetterNonAccessor.types b/tests/baselines/reference/getterSetterNonAccessor.types index 7253dcc07e6..fc707c22c36 100644 --- a/tests/baselines/reference/getterSetterNonAccessor.types +++ b/tests/baselines/reference/getterSetterNonAccessor.types @@ -9,9 +9,9 @@ function setFunc(v){} Object.defineProperty({}, "0", ({ >Object.defineProperty({}, "0", ({ get: getFunc, set: setFunc, configurable: true })) : any ->Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any +>Object.defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any >Object : ObjectConstructor ->defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any +>defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any >{} : {} >"0" : "0" >({ get: getFunc, set: setFunc, configurable: true }) : PropertyDescriptor diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index e2db782d788..ec2126f438d 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -125,14 +125,14 @@ interface P { } type NonIndexableUnion2 = string | number; ->NonIndexableUnion2 : NonIndexableUnion2 +>NonIndexableUnion2 : string | number interface Q { >Q : Q [u: NonIndexableUnion2]: A; ->u : NonIndexableUnion2 ->NonIndexableUnion2 : NonIndexableUnion2 +>u : string | number +>NonIndexableUnion2 : string | number >A : A } diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 49f44115e72..44b8b4a6051 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -28,7 +28,9 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof (T | U)'. Type 'keyof T' is not assignable to type 'keyof (T | U)'. + Type 'string' is not assignable to type 'keyof (T | U)'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,9): error TS2322: Type 'keyof T' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(88,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. Type 'keyof T' is not assignable to type 'K'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(91,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. @@ -38,6 +40,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(94,5): error tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(97,5): error TS2322: Type 'T[K]' is not assignable to type 'T[J]'. Type 'K' is not assignable to type 'J'. Type 'keyof T' is not assignable to type 'J'. + Type 'string' is not assignable to type 'J'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'. Type 'T' is not assignable to type 'U'. @@ -175,6 +178,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error ~~ !!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof (T | U)'. !!! error TS2322: Type 'keyof T' is not assignable to type 'keyof (T | U)'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof (T | U)'. k2 = k1; } @@ -186,6 +190,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error k = key // error, keyof T =/=> K ~ !!! error TS2322: Type 'keyof T' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. t[key] = tk; // ok, T[K] ==> T[keyof T] tk = t[key]; // error, T[keyof T] =/=> T[K] ~~ @@ -210,6 +215,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error !!! error TS2322: Type 'T[K]' is not assignable to type 'T[J]'. !!! error TS2322: Type 'K' is not assignable to type 'J'. !!! error TS2322: Type 'keyof T' is not assignable to type 'J'. +!!! error TS2322: Type 'string' is not assignable to type 'J'. tk = uj; uj = tk; // error diff --git a/tests/baselines/reference/library_ObjectPrototypeProperties.types b/tests/baselines/reference/library_ObjectPrototypeProperties.types index 2f41dd7c1eb..093b787a0ce 100644 --- a/tests/baselines/reference/library_ObjectPrototypeProperties.types +++ b/tests/baselines/reference/library_ObjectPrototypeProperties.types @@ -34,11 +34,11 @@ Object.prototype.valueOf(); Object.prototype.hasOwnProperty("string"); >Object.prototype.hasOwnProperty("string") : boolean ->Object.prototype.hasOwnProperty : (v: string) => boolean +>Object.prototype.hasOwnProperty : (v: string | number | symbol) => boolean >Object.prototype : Object >Object : ObjectConstructor >prototype : Object ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >"string" : "string" Object.prototype.isPrototypeOf(Object); @@ -52,10 +52,10 @@ Object.prototype.isPrototypeOf(Object); Object.prototype.propertyIsEnumerable("string"); >Object.prototype.propertyIsEnumerable("string") : boolean ->Object.prototype.propertyIsEnumerable : (v: string) => boolean +>Object.prototype.propertyIsEnumerable : (v: string | number | symbol) => boolean >Object.prototype : Object >Object : ObjectConstructor >prototype : Object ->propertyIsEnumerable : (v: string) => boolean +>propertyIsEnumerable : (v: string | number | symbol) => boolean >"string" : "string" diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index f5d0e66ff3f..ee49ef12283 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -43,12 +43,16 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(143,5): error TS Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(148,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. Type 'keyof U' is not assignable to type 'keyof T'. + Type 'string' is not assignable to type 'keyof T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(153,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: T[P]; }'. Type 'keyof T' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(158,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. Type 'keyof U' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(163,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. Type 'keyof T' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. Type 'T' is not assignable to type 'U'. @@ -272,6 +276,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. !!! error TS2322: Type 'keyof U' is not assignable to type 'keyof T'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof T'. } function f73(x: { [P in K]: T[P] }, y: { [P in keyof T]: T[P] }) { @@ -280,6 +285,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: T[P]; }'. !!! error TS2322: Type 'keyof T' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. } function f74(x: { [P in K]: T[P] }, y: { [P in keyof U]: U[P] }) { @@ -288,6 +294,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. !!! error TS2322: Type 'keyof U' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. } function f75(x: { [P in K]: T[P] }, y: { [P in keyof T]: U[P] }) { @@ -296,6 +303,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. !!! error TS2322: Type 'keyof T' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. } function f76(x: { [P in K]: T[P] }, y: { [P in K]: U[P] }) { diff --git a/tests/baselines/reference/modularizeLibrary_ErrorFromUsingES6ArrayWithOnlyES6ArrayLib.errors.txt b/tests/baselines/reference/modularizeLibrary_ErrorFromUsingES6ArrayWithOnlyES6ArrayLib.errors.txt index 82bc36819a5..4c758633a26 100644 --- a/tests/baselines/reference/modularizeLibrary_ErrorFromUsingES6ArrayWithOnlyES6ArrayLib.errors.txt +++ b/tests/baselines/reference/modularizeLibrary_ErrorFromUsingES6ArrayWithOnlyES6ArrayLib.errors.txt @@ -1,12 +1,14 @@ error TS2318: Cannot find global type 'Boolean'. error TS2318: Cannot find global type 'IArguments'. error TS2318: Cannot find global type 'Number'. +error TS2318: Cannot find global type 'Object'. tests/cases/compiler/modularizeLibrary_ErrorFromUsingES6ArrayWithOnlyES6ArrayLib.ts(3,12): error TS2693: 'Array' only refers to a type, but is being used as a value here. !!! error TS2318: Cannot find global type 'Boolean'. !!! error TS2318: Cannot find global type 'IArguments'. !!! error TS2318: Cannot find global type 'Number'. +!!! error TS2318: Cannot find global type 'Object'. ==== tests/cases/compiler/modularizeLibrary_ErrorFromUsingES6ArrayWithOnlyES6ArrayLib.ts (1 errors) ==== // Error missing basic JavaScript objects function f(x: number, y: number, z: number) { diff --git a/tests/baselines/reference/modularizeLibrary_ErrorFromUsingES6FeaturesWithOnlyES5Lib.types b/tests/baselines/reference/modularizeLibrary_ErrorFromUsingES6FeaturesWithOnlyES5Lib.types index 834449a5a82..6081b16c835 100644 --- a/tests/baselines/reference/modularizeLibrary_ErrorFromUsingES6FeaturesWithOnlyES5Lib.types +++ b/tests/baselines/reference/modularizeLibrary_ErrorFromUsingES6FeaturesWithOnlyES5Lib.types @@ -80,9 +80,9 @@ var o = { }; o.hasOwnProperty(Symbol.hasInstance); >o.hasOwnProperty(Symbol.hasInstance) : boolean ->o.hasOwnProperty : (v: string) => boolean +>o.hasOwnProperty : (v: string | number | symbol) => boolean >o : { a: number; [Symbol.hasInstance](value: any): boolean; } ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >Symbol.hasInstance : any >Symbol : any >hasInstance : any diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.symbols b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.symbols index d99084339dd..d3cd86ccfe4 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.symbols +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.symbols @@ -100,9 +100,9 @@ var o = { } }; o.hasOwnProperty(Symbol.hasInstance); ->o.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>o.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) >o : Symbol(o, Decl(modularizeLibrary_NoErrorDuplicateLibOptions1.ts, 38, 3)) ->hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) >Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) >hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types index 78e6a6bc3f5..4fdc3764e88 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types @@ -124,9 +124,9 @@ var o = { }; o.hasOwnProperty(Symbol.hasInstance); >o.hasOwnProperty(Symbol.hasInstance) : boolean ->o.hasOwnProperty : { (v: PropertyKey): boolean; (v: string): boolean; } +>o.hasOwnProperty : (v: string | number | symbol) => boolean >o : { a: number; [Symbol.hasInstance](value: any): boolean; } ->hasOwnProperty : { (v: PropertyKey): boolean; (v: string): boolean; } +>hasOwnProperty : (v: string | number | symbol) => boolean >Symbol.hasInstance : symbol >Symbol : SymbolConstructor >hasInstance : symbol diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.symbols b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.symbols index 5bb813f5c32..0450449ba64 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.symbols +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.symbols @@ -100,9 +100,9 @@ var o = { } }; o.hasOwnProperty(Symbol.hasInstance); ->o.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>o.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) >o : Symbol(o, Decl(modularizeLibrary_NoErrorDuplicateLibOptions2.ts, 38, 3)) ->hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) >Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) >hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types index 4aabae824ee..8c3ad5b55af 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types @@ -124,9 +124,9 @@ var o = { }; o.hasOwnProperty(Symbol.hasInstance); >o.hasOwnProperty(Symbol.hasInstance) : boolean ->o.hasOwnProperty : { (v: PropertyKey): boolean; (v: string): boolean; } +>o.hasOwnProperty : (v: string | number | symbol) => boolean >o : { a: number; [Symbol.hasInstance](value: any): boolean; } ->hasOwnProperty : { (v: PropertyKey): boolean; (v: string): boolean; } +>hasOwnProperty : (v: string | number | symbol) => boolean >Symbol.hasInstance : symbol >Symbol : SymbolConstructor >hasInstance : symbol diff --git a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.symbols b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.symbols index c3c24d4690e..3793215b9e2 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.symbols +++ b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.symbols @@ -100,9 +100,9 @@ var o = { } }; o.hasOwnProperty(Symbol.hasInstance); ->o.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>o.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) >o : Symbol(o, Decl(modularizeLibrary_TargetES5UsingES6Lib.ts, 38, 3)) ->hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) >Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) >hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) diff --git a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types index 2782c70ebd9..df4e231ba80 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types +++ b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types @@ -124,9 +124,9 @@ var o = { }; o.hasOwnProperty(Symbol.hasInstance); >o.hasOwnProperty(Symbol.hasInstance) : boolean ->o.hasOwnProperty : { (v: PropertyKey): boolean; (v: string): boolean; } +>o.hasOwnProperty : (v: string | number | symbol) => boolean >o : { a: number; [Symbol.hasInstance](value: any): boolean; } ->hasOwnProperty : { (v: PropertyKey): boolean; (v: string): boolean; } +>hasOwnProperty : (v: string | number | symbol) => boolean >Symbol.hasInstance : symbol >Symbol : SymbolConstructor >hasInstance : symbol diff --git a/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.symbols b/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.symbols index ba9dd82df1e..2275ddb55ff 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.symbols +++ b/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.symbols @@ -65,9 +65,9 @@ var o = { } }; o.hasOwnProperty(Symbol.hasInstance); ->o.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>o.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) >o : Symbol(o, Decl(modularizeLibrary_TargetES6UsingES6Lib.ts, 21, 3)) ->hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) >Symbol.hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) >hasInstance : Symbol(SymbolConstructor.hasInstance, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) diff --git a/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.types b/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.types index 9c0f81701dc..1902ac93f05 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.types +++ b/tests/baselines/reference/modularizeLibrary_TargetES6UsingES6Lib.types @@ -79,9 +79,9 @@ var o = { }; o.hasOwnProperty(Symbol.hasInstance); >o.hasOwnProperty(Symbol.hasInstance) : boolean ->o.hasOwnProperty : { (v: string): boolean; (v: PropertyKey): boolean; } +>o.hasOwnProperty : (v: string | number | symbol) => boolean >o : { a: number; [Symbol.hasInstance](value: any): boolean; } ->hasOwnProperty : { (v: string): boolean; (v: PropertyKey): boolean; } +>hasOwnProperty : (v: string | number | symbol) => boolean >Symbol.hasInstance : symbol >Symbol : SymbolConstructor >hasInstance : symbol diff --git a/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6FeatureLibs.types b/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6FeatureLibs.types index ab24aaf12ba..e9213203637 100644 --- a/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6FeatureLibs.types +++ b/tests/baselines/reference/modularizeLibrary_UsingES5LibAndES6FeatureLibs.types @@ -16,10 +16,10 @@ var p = new Proxy(t, {}); >{} : {} Reflect.ownKeys({}); ->Reflect.ownKeys({}) : PropertyKey[] ->Reflect.ownKeys : (target: object) => PropertyKey[] +>Reflect.ownKeys({}) : (string | number | symbol)[] +>Reflect.ownKeys : (target: object) => (string | number | symbol)[] >Reflect : typeof Reflect ->ownKeys : (target: object) => PropertyKey[] +>ownKeys : (target: object) => (string | number | symbol)[] >{} : {} function* idGen() { diff --git a/tests/baselines/reference/neverUnionIntersection.types b/tests/baselines/reference/neverUnionIntersection.types index 4f578052e9c..5d9085e72e6 100644 --- a/tests/baselines/reference/neverUnionIntersection.types +++ b/tests/baselines/reference/neverUnionIntersection.types @@ -6,7 +6,7 @@ type T02 = string & never; >T02 : never type T03 = string | number | never; ->T03 : T03 +>T03 : string | number type T04 = string & number & never; >T04 : never diff --git a/tests/baselines/reference/numberPropertyAccess.types b/tests/baselines/reference/numberPropertyAccess.types index e7ffcbc246d..b2baf38873c 100644 --- a/tests/baselines/reference/numberPropertyAccess.types +++ b/tests/baselines/reference/numberPropertyAccess.types @@ -13,9 +13,9 @@ var a = x.toExponential(); var b = x.hasOwnProperty('toFixed'); >b : boolean >x.hasOwnProperty('toFixed') : boolean ->x.hasOwnProperty : (v: string) => boolean +>x.hasOwnProperty : (v: string | number | symbol) => boolean >x : number ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >'toFixed' : "toFixed" var c = x['toExponential'](); @@ -28,7 +28,7 @@ var c = x['toExponential'](); var d = x['hasOwnProperty']('toFixed'); >d : boolean >x['hasOwnProperty']('toFixed') : boolean ->x['hasOwnProperty'] : (v: string) => boolean +>x['hasOwnProperty'] : (v: string | number | symbol) => boolean >x : number >'hasOwnProperty' : "hasOwnProperty" >'toFixed' : "toFixed" diff --git a/tests/baselines/reference/objectLitGetterSetter.types b/tests/baselines/reference/objectLitGetterSetter.types index c2ce173e029..05c748162d9 100644 --- a/tests/baselines/reference/objectLitGetterSetter.types +++ b/tests/baselines/reference/objectLitGetterSetter.types @@ -5,9 +5,9 @@ Object.defineProperty(obj, "accProperty", ({ >Object.defineProperty(obj, "accProperty", ({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } })) : any ->Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any +>Object.defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any >Object : ObjectConstructor ->defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any +>defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any >obj : {} >"accProperty" : "accProperty" >({ get: function () { eval("public = 1;"); return 11; }, set: function (v) { } }) : PropertyDescriptor diff --git a/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt b/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt index 19c12ebf62f..4f27c62e67d 100644 --- a/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt +++ b/tests/baselines/reference/objectTypeHidingMembersOfExtendedObject.errors.txt @@ -1,8 +1,8 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'data' of type 'A' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'hasOwnProperty' of type '(v: string) => boolean' is not assignable to string index type 'Object'. +tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'hasOwnProperty' of type '(v: string | number | symbol) => boolean' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: string) => boolean' is not assignable to string index type 'Object'. +tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: string | number | symbol) => boolean' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts(11,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. @@ -25,11 +25,11 @@ tests/cases/conformance/types/members/objectTypeHidingMembersOfExtendedObject.ts ~~~~~~~~~~~~~~~~~~~~ !!! error TS2411: Property 'data' of type 'A' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'hasOwnProperty' of type '(v: string) => boolean' is not assignable to string index type 'Object'. +!!! error TS2411: Property 'hasOwnProperty' of type '(v: string | number | symbol) => boolean' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ !!! error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'propertyIsEnumerable' of type '(v: string) => boolean' is not assignable to string index type 'Object'. +!!! error TS2411: Property 'propertyIsEnumerable' of type '(v: string | number | symbol) => boolean' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ !!! error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt b/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt index d09701c3b06..2fadffd195d 100644 --- a/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt +++ b/tests/baselines/reference/objectTypeWithStringIndexerHidingObjectIndexer.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'hasOwnProperty' of type '(v: string) => boolean' is not assignable to string index type 'Object'. +tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'hasOwnProperty' of type '(v: string | number | symbol) => boolean' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. -tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: string) => boolean' is not assignable to string index type 'Object'. +tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'propertyIsEnumerable' of type '(v: string | number | symbol) => boolean' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'toString' of type '() => string' is not assignable to string index type 'Object'. tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectIndexer.ts(5,5): error TS2411: Property 'valueOf' of type '() => Object' is not assignable to string index type 'Object'. @@ -16,11 +16,11 @@ tests/cases/conformance/types/members/objectTypeWithStringIndexerHidingObjectInd ~~~~~~~~~~~~~~~~~~~~ !!! error TS2411: Property 'constructor' of type 'Function' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'hasOwnProperty' of type '(v: string) => boolean' is not assignable to string index type 'Object'. +!!! error TS2411: Property 'hasOwnProperty' of type '(v: string | number | symbol) => boolean' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ !!! error TS2411: Property 'isPrototypeOf' of type '(v: Object) => boolean' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ -!!! error TS2411: Property 'propertyIsEnumerable' of type '(v: string) => boolean' is not assignable to string index type 'Object'. +!!! error TS2411: Property 'propertyIsEnumerable' of type '(v: string | number | symbol) => boolean' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ !!! error TS2411: Property 'toLocaleString' of type '() => string' is not assignable to string index type 'Object'. ~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/parserUsingConstructorAsIdentifier.types b/tests/baselines/reference/parserUsingConstructorAsIdentifier.types index fa5e60a12b8..d0cd25f887d 100644 --- a/tests/baselines/reference/parserUsingConstructorAsIdentifier.types +++ b/tests/baselines/reference/parserUsingConstructorAsIdentifier.types @@ -90,9 +90,9 @@ Object.defineProperty(constructor.prototype, "constructor", { value: constructor, writable: true, configurable: true, enumerable: true }); >Object.defineProperty(constructor.prototype, "constructor", { value: constructor, writable: true, configurable: true, enumerable: true }) : any ->Object.defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any +>Object.defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any >Object : ObjectConstructor ->defineProperty : (o: any, p: string, attributes: PropertyDescriptor & ThisType) => any +>defineProperty : (o: any, p: string | number | symbol, attributes: PropertyDescriptor & ThisType) => any >constructor.prototype : any >constructor : any >prototype : any diff --git a/tests/baselines/reference/parserharness.types b/tests/baselines/reference/parserharness.types index 505cfe67c82..cc8bae97706 100644 --- a/tests/baselines/reference/parserharness.types +++ b/tests/baselines/reference/parserharness.types @@ -2810,11 +2810,11 @@ module Harness { if (this.fileCollection.hasOwnProperty(p)) { >this.fileCollection.hasOwnProperty(p) : boolean ->this.fileCollection.hasOwnProperty : (v: string) => boolean +>this.fileCollection.hasOwnProperty : (v: string | number | symbol) => boolean >this.fileCollection : {} >this : this >fileCollection : {} ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >p : string var current = this.fileCollection[p]; diff --git a/tests/baselines/reference/propertyAccess.types b/tests/baselines/reference/propertyAccess.types index 983718ee1fd..82af3d51316 100644 --- a/tests/baselines/reference/propertyAccess.types +++ b/tests/baselines/reference/propertyAccess.types @@ -139,10 +139,10 @@ var aa = obj.x; // Dotted property access of property that exists on value's apparent type var bb = obj.hasOwnProperty; ->bb : (v: string) => boolean ->obj.hasOwnProperty : (v: string) => boolean +>bb : (v: string | number | symbol) => boolean +>obj.hasOwnProperty : (v: string | number | symbol) => boolean >obj : { 10: string; x: string; y: number; z: { n: string; m: number; o: () => boolean; }; 'literal property': number; } ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean // Dotted property access of property that doesn't exist on value's apparent type var cc = obj.qqq; // error diff --git a/tests/baselines/reference/staticInstanceResolution2.types b/tests/baselines/reference/staticInstanceResolution2.types index 68abb3a08ce..e44f99d212f 100644 --- a/tests/baselines/reference/staticInstanceResolution2.types +++ b/tests/baselines/reference/staticInstanceResolution2.types @@ -4,9 +4,9 @@ class A { } A.hasOwnProperty('foo'); >A.hasOwnProperty('foo') : boolean ->A.hasOwnProperty : (v: string) => boolean +>A.hasOwnProperty : (v: string | number | symbol) => boolean >A : typeof A ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >'foo' : "foo" class B { @@ -16,9 +16,9 @@ class B { } B.hasOwnProperty('foo'); >B.hasOwnProperty('foo') : boolean ->B.hasOwnProperty : (v: string) => boolean +>B.hasOwnProperty : (v: string | number | symbol) => boolean >B : typeof B ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >'foo' : "foo" diff --git a/tests/baselines/reference/stringPropertyAccess.types b/tests/baselines/reference/stringPropertyAccess.types index fd2ec13da74..da8298178b6 100644 --- a/tests/baselines/reference/stringPropertyAccess.types +++ b/tests/baselines/reference/stringPropertyAccess.types @@ -14,9 +14,9 @@ var a = x.charAt(0); var b = x.hasOwnProperty('charAt'); >b : boolean >x.hasOwnProperty('charAt') : boolean ->x.hasOwnProperty : (v: string) => boolean +>x.hasOwnProperty : (v: string | number | symbol) => boolean >x : string ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >'charAt' : "charAt" var c = x['charAt'](0); @@ -30,7 +30,7 @@ var c = x['charAt'](0); var e = x['hasOwnProperty']('toFixed'); >e : boolean >x['hasOwnProperty']('toFixed') : boolean ->x['hasOwnProperty'] : (v: string) => boolean +>x['hasOwnProperty'] : (v: string | number | symbol) => boolean >x : string >'hasOwnProperty' : "hasOwnProperty" >'toFixed' : "toFixed" diff --git a/tests/baselines/reference/symbolType1.symbols b/tests/baselines/reference/symbolType1.symbols index ded0dcff47b..98c6a263632 100644 --- a/tests/baselines/reference/symbolType1.symbols +++ b/tests/baselines/reference/symbolType1.symbols @@ -9,7 +9,7 @@ Symbol instanceof Symbol(); (Symbol() || {}) instanceof Object; // This one should be okay, it's a valid way of distinguishing types >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) Symbol instanceof (Symbol() || {}); >Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) diff --git a/tests/baselines/reference/typePredicateStructuralMatch.types b/tests/baselines/reference/typePredicateStructuralMatch.types index 9f7a129da15..c01f5f5b06a 100644 --- a/tests/baselines/reference/typePredicateStructuralMatch.types +++ b/tests/baselines/reference/typePredicateStructuralMatch.types @@ -46,9 +46,9 @@ function isResponseInData(value: T | { data: T}): value is { data: T } { return value.hasOwnProperty('data'); >value.hasOwnProperty('data') : boolean ->value.hasOwnProperty : (v: string) => boolean +>value.hasOwnProperty : (v: string | number | symbol) => boolean >value : T | { data: T; } ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >'data' : "data" } @@ -84,9 +84,9 @@ function isPlainResponse(value: T | { data: T}): value is T { return !value.hasOwnProperty('data'); >!value.hasOwnProperty('data') : boolean >value.hasOwnProperty('data') : boolean ->value.hasOwnProperty : (v: string) => boolean +>value.hasOwnProperty : (v: string | number | symbol) => boolean >value : T | { data: T; } ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >'data' : "data" } diff --git a/tests/baselines/reference/unspecializedConstraints.types b/tests/baselines/reference/unspecializedConstraints.types index f5d081968d9..4c3d0c00d0d 100644 --- a/tests/baselines/reference/unspecializedConstraints.types +++ b/tests/baselines/reference/unspecializedConstraints.types @@ -464,12 +464,12 @@ module ts { var hasOwnProperty = Object.prototype.hasOwnProperty; ->hasOwnProperty : (v: string) => boolean ->Object.prototype.hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean +>Object.prototype.hasOwnProperty : (v: string | number | symbol) => boolean >Object.prototype : Object >Object : ObjectConstructor >prototype : Object ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean function getProperty(map: Map, key: string): T { >getProperty : (map: Map, key: string) => T @@ -484,7 +484,7 @@ module ts { >!hasOwnProperty.call(map, key) : boolean >hasOwnProperty.call(map, key) : any >hasOwnProperty.call : (this: Function, thisArg: any, ...argArray: any[]) => any ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >call : (this: Function, thisArg: any, ...argArray: any[]) => any >map : Map >key : string @@ -507,7 +507,7 @@ module ts { return hasOwnProperty.call(map, key); >hasOwnProperty.call(map, key) : any >hasOwnProperty.call : (this: Function, thisArg: any, ...argArray: any[]) => any ->hasOwnProperty : (v: string) => boolean +>hasOwnProperty : (v: string | number | symbol) => boolean >call : (this: Function, thisArg: any, ...argArray: any[]) => any >map : Map >key : string diff --git a/tests/baselines/reference/useObjectValuesAndEntries3.symbols b/tests/baselines/reference/useObjectValuesAndEntries3.symbols index 65d5175eaa6..51f2b14cc93 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries3.symbols +++ b/tests/baselines/reference/useObjectValuesAndEntries3.symbols @@ -6,7 +6,7 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : Symbol(x, Decl(useObjectValuesAndEntries3.ts, 2, 8)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries3.ts, 0, 3)) let y = x; @@ -16,6 +16,6 @@ for (var x of Object.values(o)) { var entries = Object.entries(o); >entries : Symbol(entries, Decl(useObjectValuesAndEntries3.ts, 6, 3)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries3.ts, 0, 3)) diff --git a/tests/baselines/reference/useObjectValuesAndEntries4.symbols b/tests/baselines/reference/useObjectValuesAndEntries4.symbols index adef865c04c..8c087361e7d 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries4.symbols +++ b/tests/baselines/reference/useObjectValuesAndEntries4.symbols @@ -7,7 +7,7 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : Symbol(x, Decl(useObjectValuesAndEntries4.ts, 2, 8)) >Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries4.ts, 0, 3)) @@ -19,7 +19,7 @@ for (var x of Object.values(o)) { var entries = Object.entries(o); >entries : Symbol(entries, Decl(useObjectValuesAndEntries4.ts, 6, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) ->Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries4.ts, 0, 3)) From 6d93f3083975a2246c4dee76856ac06798789d39 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 9 Apr 2018 08:51:26 -1000 Subject: [PATCH 010/229] Enable 'keyof T' for full string | number | symbol --- src/compiler/checker.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fb0e279df37..e6ba58987fb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -72,7 +72,7 @@ namespace ts { const strictPropertyInitialization = getStrictOptionValue(compilerOptions, "strictPropertyInitialization"); const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny"); const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis"); - const keyofStringsOnly = true; // !!compilerOptions.keyofStringsOnly; + const keyofStringsOnly = !!compilerOptions.keyofStringsOnly; const emitResolver = createResolver(); const nodeBuilder = createNodeBuilder(); @@ -347,7 +347,6 @@ namespace ts { const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); const implicitNeverType = createIntrinsicType(TypeFlags.Never, "never"); const nonPrimitiveType = createIntrinsicType(TypeFlags.NonPrimitive, "object"); - const stringNumberType = getUnionType([stringType, numberType]); const stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]); const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType; @@ -8147,24 +8146,15 @@ namespace ts { return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined; } - function getStringOnlyIndexType(type: Type) { - return type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? stringType : - getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral); - } - - function getStringNumberSymbolIndexType(type: Type) { - return type.flags & TypeFlags.Any ? stringNumberSymbolType : - getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringNumberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : - getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : - getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol); - } - function getIndexType(type: Type): Type { return type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t))) : maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : - keyofStringsOnly ? getStringOnlyIndexType(type) : getStringNumberSymbolIndexType(type); + type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? keyofConstraintType : + keyofStringsOnly ? getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : + getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : + getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol); } function getExtractStringType(type: Type) { From 0379666bbf099c943dc8b3681737b669f1823997 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 9 Apr 2018 08:51:55 -1000 Subject: [PATCH 011/229] Update tests --- tests/cases/compiler/deeplyNestedCheck.ts | 2 +- tests/cases/compiler/deferredLookupTypeResolution.ts | 2 +- tests/cases/compiler/deferredLookupTypeResolution2.ts | 2 +- tests/cases/compiler/indexedAccessRetainsIndexSignature.ts | 2 +- tests/cases/compiler/recursiveTypeRelations.ts | 2 +- tests/cases/conformance/types/conditional/conditionalTypes1.ts | 2 +- tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts | 2 +- .../conformance/types/keyof/keyofAndIndexedAccessErrors.ts | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/cases/compiler/deeplyNestedCheck.ts b/tests/cases/compiler/deeplyNestedCheck.ts index e95233af985..366599be966 100644 --- a/tests/cases/compiler/deeplyNestedCheck.ts +++ b/tests/cases/compiler/deeplyNestedCheck.ts @@ -5,5 +5,5 @@ interface DataSnapshot { } interface Snapshot extends DataSnapshot { - child(path: U): Snapshot; + child>(path: U): Snapshot; } diff --git a/tests/cases/compiler/deferredLookupTypeResolution.ts b/tests/cases/compiler/deferredLookupTypeResolution.ts index 6c9853266ad..2970540afbd 100644 --- a/tests/cases/compiler/deferredLookupTypeResolution.ts +++ b/tests/cases/compiler/deferredLookupTypeResolution.ts @@ -8,7 +8,7 @@ type StringContains = ( { [key: string]: 'false' } )[L] -type ObjectHasKey = StringContains +type ObjectHasKey = StringContains, L> type First = ObjectHasKey; // Should be deferred diff --git a/tests/cases/compiler/deferredLookupTypeResolution2.ts b/tests/cases/compiler/deferredLookupTypeResolution2.ts index 4aa18c092ba..6b8a161e6df 100644 --- a/tests/cases/compiler/deferredLookupTypeResolution2.ts +++ b/tests/cases/compiler/deferredLookupTypeResolution2.ts @@ -5,7 +5,7 @@ type StringContains = ({ [K in S]: 'true' } & { [key: string]: 'false'})[L]; -type ObjectHasKey = StringContains; +type ObjectHasKey = StringContains, L>; type A = ObjectHasKey; diff --git a/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts b/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts index d23cbe87ddf..11abf771edc 100644 --- a/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts +++ b/tests/cases/compiler/indexedAccessRetainsIndexSignature.ts @@ -1,4 +1,4 @@ -type Diff = +type Diff = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] type Omit = Pick> type Omit1 = Pick>; diff --git a/tests/cases/compiler/recursiveTypeRelations.ts b/tests/cases/compiler/recursiveTypeRelations.ts index 18545300f77..f9f71ae04b1 100644 --- a/tests/cases/compiler/recursiveTypeRelations.ts +++ b/tests/cases/compiler/recursiveTypeRelations.ts @@ -1,6 +1,6 @@ // Repro from #14896 -type Attributes = { +type Attributes = { [Key in Keys]: string; } diff --git a/tests/cases/conformance/types/conditional/conditionalTypes1.ts b/tests/cases/conformance/types/conditional/conditionalTypes1.ts index 638cf473e19..f5c67f678eb 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes1.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes1.ts @@ -303,7 +303,7 @@ function f50() { // Repro from #21862 -type OldDiff = ( +type OldDiff = ( & { [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; } diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index 9ec4e820f73..447fdebf68e 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -556,7 +556,7 @@ class AnotherSampleClass extends SampleClass { new AnotherSampleClass({}); // Positive repro from #17166 -function f3(t: T, k: K, tk: T[K]): void { +function f3>(t: T, k: K, tk: T[K]): void { for (let key in t) { key = k // ok, K ==> keyof T t[key] = tk; // ok, T[K] ==> T[keyof T] diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts index f96bcdb6234..618f483655e 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts @@ -79,7 +79,7 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { } // Repro from #17166 -function f3( +function f3, U extends T, J extends K>( t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void { for (let key in t) { key = k // ok, K ==> keyof T From b1545fe5eff229b3b04efb5e791954c40c630780 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 9 Apr 2018 08:52:20 -1000 Subject: [PATCH 012/229] Accept new baselines --- .../reference/conditionalTypes1.errors.txt | 118 ++++++++++-------- .../baselines/reference/conditionalTypes1.js | 4 +- .../reference/conditionalTypes1.symbols | 6 +- .../reference/conditionalTypes1.types | 2 +- .../reference/conditionalTypes2.errors.txt | 6 +- .../baselines/reference/deeplyNestedCheck.js | 2 +- .../reference/deeplyNestedCheck.symbols | 5 +- .../reference/deeplyNestedCheck.types | 5 +- .../reference/deferredLookupTypeResolution.js | 4 +- .../deferredLookupTypeResolution.symbols | 5 +- .../deferredLookupTypeResolution.types | 13 +- .../deferredLookupTypeResolution2.errors.txt | 10 +- .../deferredLookupTypeResolution2.js | 4 +- .../deferredLookupTypeResolution2.symbols | 7 +- .../deferredLookupTypeResolution2.types | 31 ++--- .../reference/for-inStatements.errors.txt | 8 +- .../for-inStatementsInvalid.errors.txt | 8 +- .../baselines/reference/forInStatement3.types | 2 +- .../reference/implicitAnyInCatch.types | 2 +- .../reference/inOperatorWithGeneric.types | 2 +- .../indexedAccessRetainsIndexSignature.js | 2 +- ...indexedAccessRetainsIndexSignature.symbols | 6 +- .../indexedAccessRetainsIndexSignature.types | 2 +- .../reference/indexerConstraints2.types | 6 +- .../reference/inferTypes1.errors.txt | 6 +- .../isomorphicMappedTypeInference.types | 44 +++---- tests/baselines/reference/keyofAndForIn.types | 24 ++-- .../reference/keyofAndIndexedAccess.js | 4 +- .../reference/keyofAndIndexedAccess.symbols | 17 +-- .../reference/keyofAndIndexedAccess.types | 43 +++---- .../keyofAndIndexedAccessErrors.errors.txt | 36 +++--- .../reference/keyofAndIndexedAccessErrors.js | 2 +- .../keyofAndIndexedAccessErrors.symbols | 27 ++-- .../keyofAndIndexedAccessErrors.types | 35 +++--- ...ndConstraintTypeChecksCorrectly.errors.txt | 29 ----- .../reference/mappedTypeErrors.errors.txt | 23 ++-- .../reference/mappedTypeErrors.types | 24 ++-- .../mappedTypeRelationships.errors.txt | 24 ++-- .../reference/mappedTypeWithAny.types | 2 +- tests/baselines/reference/mappedTypes4.types | 16 +-- .../reference/neverUnionIntersection.types | 2 +- .../recursiveTypeRelations.errors.txt | 2 +- .../reference/recursiveTypeRelations.js | 2 +- .../reference/recursiveTypeRelations.symbols | 2 +- .../reference/recursiveTypeRelations.types | 2 +- .../reference/typeGuardsTypeParameters.types | 12 +- 46 files changed, 330 insertions(+), 308 deletions(-) delete mode 100644 tests/baselines/reference/lateBoundConstraintTypeChecksCorrectly.errors.txt diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index 5d1f72c14a0..acb72d2cb56 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -20,32 +20,39 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(106,5): error TS2 Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'keyof T' is not assignable to type 'never'. - Type 'string' is not assignable to type 'never'. + Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'never'. + Type 'string | number | symbol' is not assignable to type 'never'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(108,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'keyof T' is not assignable to type 'never'. + Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(115,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. @@ -53,12 +60,15 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(115,5): error TS2 Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. Type 'keyof T' is not assignable to type 'never'. - Type 'string' is not assignable to type 'never'. + Type 'string | number | symbol' is not assignable to type 'never'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(116,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(117,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. @@ -221,15 +231,18 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. !!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. !!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. !!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. -!!! error TS2322: Type 'string' is not assignable to type 'never'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. z = x; z = y; // Error ~ @@ -237,14 +250,16 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. !!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. !!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. !!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. } function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { @@ -253,10 +268,12 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS y = x; // Error ~ !!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. y = z; // Error ~ !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. @@ -266,14 +283,17 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. !!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. !!! error TS2322: Type 'keyof T' is not assignable to type 'never'. -!!! error TS2322: Type 'string' is not assignable to type 'never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. z = x; // Error ~ !!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. z = y; // Error ~ !!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. @@ -491,7 +511,7 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS // Repro from #21862 - type OldDiff = ( + type OldDiff = ( & { [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; } diff --git a/tests/baselines/reference/conditionalTypes1.js b/tests/baselines/reference/conditionalTypes1.js index 3e5e385625b..552a80d58a5 100644 --- a/tests/baselines/reference/conditionalTypes1.js +++ b/tests/baselines/reference/conditionalTypes1.js @@ -301,7 +301,7 @@ function f50() { // Repro from #21862 -type OldDiff = ( +type OldDiff = ( & { [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; } @@ -656,7 +656,7 @@ declare type T95 = T extends string ? boolean : number; declare const f44: (value: T94) => T95; declare const f45: (value: T95) => T94; declare function f50(): void; -declare type OldDiff = ({ +declare type OldDiff = ({ [P in T]: P; } & { [P in U]: never; diff --git a/tests/baselines/reference/conditionalTypes1.symbols b/tests/baselines/reference/conditionalTypes1.symbols index fb0ce83e0a7..5f6bb75514d 100644 --- a/tests/baselines/reference/conditionalTypes1.symbols +++ b/tests/baselines/reference/conditionalTypes1.symbols @@ -1186,10 +1186,10 @@ function f50() { // Repro from #21862 -type OldDiff = ( +type OldDiff = ( >OldDiff : Symbol(OldDiff, Decl(conditionalTypes1.ts, 298, 1)) >T : Symbol(T, Decl(conditionalTypes1.ts, 302, 13)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 302, 30)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 302, 33)) & { [P in T]: P; } >P : Symbol(P, Decl(conditionalTypes1.ts, 303, 9)) @@ -1198,7 +1198,7 @@ type OldDiff = ( & { [P in U]: never; } >P : Symbol(P, Decl(conditionalTypes1.ts, 304, 9)) ->U : Symbol(U, Decl(conditionalTypes1.ts, 302, 30)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 302, 33)) & { [x: string]: never; } >x : Symbol(x, Decl(conditionalTypes1.ts, 305, 9)) diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index 2ba376781a5..90d2703d034 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -1343,7 +1343,7 @@ function f50() { // Repro from #21862 -type OldDiff = ( +type OldDiff = ( >OldDiff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] >T : T >U : U diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt index 41adb72f62d..127e94196f6 100644 --- a/tests/baselines/reference/conditionalTypes2.errors.txt +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -6,7 +6,8 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(24,5): error TS23 Types of property 'foo' are incompatible. Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'. Type 'keyof B' is not assignable to type 'keyof A'. - Type 'string' is not assignable to type 'keyof A'. + Type 'string | number | symbol' is not assignable to type 'keyof A'. + Type 'string' is not assignable to type 'keyof A'. tests/cases/conformance/types/conditional/conditionalTypes2.ts(25,5): error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. Types of property 'foo' are incompatible. Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'. @@ -61,7 +62,8 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2 !!! error TS2322: Types of property 'foo' are incompatible. !!! error TS2322: Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'. !!! error TS2322: Type 'keyof B' is not assignable to type 'keyof A'. -!!! error TS2322: Type 'string' is not assignable to type 'keyof A'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof A'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof A'. b = a; // Error ~ !!! error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. diff --git a/tests/baselines/reference/deeplyNestedCheck.js b/tests/baselines/reference/deeplyNestedCheck.js index 466ae94f12d..ccd234e2580 100644 --- a/tests/baselines/reference/deeplyNestedCheck.js +++ b/tests/baselines/reference/deeplyNestedCheck.js @@ -6,7 +6,7 @@ interface DataSnapshot { } interface Snapshot extends DataSnapshot { - child(path: U): Snapshot; + child>(path: U): Snapshot; } diff --git a/tests/baselines/reference/deeplyNestedCheck.symbols b/tests/baselines/reference/deeplyNestedCheck.symbols index a8b5af60880..80c531cd6d0 100644 --- a/tests/baselines/reference/deeplyNestedCheck.symbols +++ b/tests/baselines/reference/deeplyNestedCheck.symbols @@ -16,11 +16,12 @@ interface Snapshot extends DataSnapshot { >T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19)) >DataSnapshot : Symbol(DataSnapshot, Decl(deeplyNestedCheck.ts, 0, 0)) - child(path: U): Snapshot; + child>(path: U): Snapshot; >child : Symbol(Snapshot.child, Decl(deeplyNestedCheck.ts, 6, 44)) >U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) >T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19)) ->path : Symbol(path, Decl(deeplyNestedCheck.ts, 7, 27)) +>path : Symbol(path, Decl(deeplyNestedCheck.ts, 7, 44)) >U : Symbol(U, Decl(deeplyNestedCheck.ts, 7, 8)) >Snapshot : Symbol(Snapshot, Decl(deeplyNestedCheck.ts, 4, 1)) >T : Symbol(T, Decl(deeplyNestedCheck.ts, 6, 19)) diff --git a/tests/baselines/reference/deeplyNestedCheck.types b/tests/baselines/reference/deeplyNestedCheck.types index e500fc75ed1..dc8550bc2cb 100644 --- a/tests/baselines/reference/deeplyNestedCheck.types +++ b/tests/baselines/reference/deeplyNestedCheck.types @@ -16,9 +16,10 @@ interface Snapshot extends DataSnapshot { >T : T >DataSnapshot : DataSnapshot - child(path: U): Snapshot; ->child : (path: U) => Snapshot + child>(path: U): Snapshot; +>child : >(path: U) => Snapshot >U : U +>Extract : Extract >T : T >path : U >U : U diff --git a/tests/baselines/reference/deferredLookupTypeResolution.js b/tests/baselines/reference/deferredLookupTypeResolution.js index e5baa6891e8..126f9d1345a 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution.js +++ b/tests/baselines/reference/deferredLookupTypeResolution.js @@ -6,7 +6,7 @@ type StringContains = ( { [key: string]: 'false' } )[L] -type ObjectHasKey = StringContains +type ObjectHasKey = StringContains, L> type First = ObjectHasKey; // Should be deferred @@ -43,7 +43,7 @@ declare type StringContains = ({ } & { [key: string]: 'false'; })[L]; -declare type ObjectHasKey = StringContains; +declare type ObjectHasKey = StringContains, L>; declare type First = ObjectHasKey; declare type T1 = ObjectHasKey<{ a: string; diff --git a/tests/baselines/reference/deferredLookupTypeResolution.symbols b/tests/baselines/reference/deferredLookupTypeResolution.symbols index 022dc3cc2f4..29906ac6ae1 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution.symbols +++ b/tests/baselines/reference/deferredLookupTypeResolution.symbols @@ -16,16 +16,17 @@ type StringContains = ( )[L] >L : Symbol(L, Decl(deferredLookupTypeResolution.ts, 2, 37)) -type ObjectHasKey = StringContains +type ObjectHasKey = StringContains, L> >ObjectHasKey : Symbol(ObjectHasKey, Decl(deferredLookupTypeResolution.ts, 5, 6)) >O : Symbol(O, Decl(deferredLookupTypeResolution.ts, 7, 18)) >L : Symbol(L, Decl(deferredLookupTypeResolution.ts, 7, 20)) >StringContains : Symbol(StringContains, Decl(deferredLookupTypeResolution.ts, 0, 0)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) >O : Symbol(O, Decl(deferredLookupTypeResolution.ts, 7, 18)) >L : Symbol(L, Decl(deferredLookupTypeResolution.ts, 7, 20)) type First = ObjectHasKey; // Should be deferred ->First : Symbol(First, Decl(deferredLookupTypeResolution.ts, 7, 67)) +>First : Symbol(First, Decl(deferredLookupTypeResolution.ts, 7, 84)) >T : Symbol(T, Decl(deferredLookupTypeResolution.ts, 9, 11)) >ObjectHasKey : Symbol(ObjectHasKey, Decl(deferredLookupTypeResolution.ts, 5, 6)) >T : Symbol(T, Decl(deferredLookupTypeResolution.ts, 9, 11)) diff --git a/tests/baselines/reference/deferredLookupTypeResolution.types b/tests/baselines/reference/deferredLookupTypeResolution.types index cd123a6019e..4826b03329a 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution.types +++ b/tests/baselines/reference/deferredLookupTypeResolution.types @@ -16,28 +16,29 @@ type StringContains = ( )[L] >L : L -type ObjectHasKey = StringContains ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +type ObjectHasKey = StringContains, L> +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] >O : O >L : L >StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>Extract : Extract >O : O >L : L type First = ObjectHasKey; // Should be deferred ->First : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] +>First : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })["0"] >T : T ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] >T : T type T1 = ObjectHasKey<{ a: string }, 'a'>; // 'true' >T1 : "true" ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] >a : string type T2 = ObjectHasKey<{ a: string }, 'b'>; // 'false' >T2 : "false" ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] >a : string // Verify that mapped type isn't eagerly resolved in type-to-string operation diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt b/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt index 6d1d579c0ad..88bcd2c4340 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt +++ b/tests/baselines/reference/deferredLookupTypeResolution2.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/deferredLookupTypeResolution2.ts(14,13): error TS2536: Type '({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. -tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. +tests/cases/compiler/deferredLookupTypeResolution2.ts(14,13): error TS2536: Type '({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. +tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. ==== tests/cases/compiler/deferredLookupTypeResolution2.ts (2 errors) ==== @@ -7,7 +7,7 @@ tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type type StringContains = ({ [K in S]: 'true' } & { [key: string]: 'false'})[L]; - type ObjectHasKey = StringContains; + type ObjectHasKey = StringContains, L>; type A = ObjectHasKey; @@ -18,14 +18,14 @@ tests/cases/compiler/deferredLookupTypeResolution2.ts(19,21): error TS2536: Type // Error, "false" not handled type E = { true: 'true' }[ObjectHasKey]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2536: Type '({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. +!!! error TS2536: Type '({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]' cannot be used to index type '{ true: "true"; }'. type Juxtapose = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey]; // Error, "otherwise" is missing type DeepError = { true: 'true' }[Juxtapose]; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. +!!! error TS2536: Type '({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]]' cannot be used to index type '{ true: "true"; }'. type DeepOK = { true: 'true', otherwise: 'false' }[Juxtapose]; \ No newline at end of file diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.js b/tests/baselines/reference/deferredLookupTypeResolution2.js index 97289f47f9c..3d40dcb4bbf 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution2.js +++ b/tests/baselines/reference/deferredLookupTypeResolution2.js @@ -3,7 +3,7 @@ type StringContains = ({ [K in S]: 'true' } & { [key: string]: 'false'})[L]; -type ObjectHasKey = StringContains; +type ObjectHasKey = StringContains, L>; type A = ObjectHasKey; @@ -33,7 +33,7 @@ declare type StringContains = ({ } & { [key: string]: 'false'; })[L]; -declare type ObjectHasKey = StringContains; +declare type ObjectHasKey = StringContains, L>; declare type A = ObjectHasKey; declare type B = ObjectHasKey<[string, number], '1'>; declare type C = ObjectHasKey<[string, number], '2'>; diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.symbols b/tests/baselines/reference/deferredLookupTypeResolution2.symbols index ca55b3e407e..41064fae533 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution2.symbols +++ b/tests/baselines/reference/deferredLookupTypeResolution2.symbols @@ -10,16 +10,17 @@ type StringContains = ({ [K in S]: 'true' } >key : Symbol(key, Decl(deferredLookupTypeResolution2.ts, 2, 85)) >L : Symbol(L, Decl(deferredLookupTypeResolution2.ts, 2, 37)) -type ObjectHasKey = StringContains; +type ObjectHasKey = StringContains, L>; >ObjectHasKey : Symbol(ObjectHasKey, Decl(deferredLookupTypeResolution2.ts, 2, 112)) >O : Symbol(O, Decl(deferredLookupTypeResolution2.ts, 4, 18)) >L : Symbol(L, Decl(deferredLookupTypeResolution2.ts, 4, 20)) >StringContains : Symbol(StringContains, Decl(deferredLookupTypeResolution2.ts, 0, 0)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) >O : Symbol(O, Decl(deferredLookupTypeResolution2.ts, 4, 18)) >L : Symbol(L, Decl(deferredLookupTypeResolution2.ts, 4, 20)) type A = ObjectHasKey; ->A : Symbol(A, Decl(deferredLookupTypeResolution2.ts, 4, 68)) +>A : Symbol(A, Decl(deferredLookupTypeResolution2.ts, 4, 85)) >T : Symbol(T, Decl(deferredLookupTypeResolution2.ts, 6, 7)) >ObjectHasKey : Symbol(ObjectHasKey, Decl(deferredLookupTypeResolution2.ts, 2, 112)) >T : Symbol(T, Decl(deferredLookupTypeResolution2.ts, 6, 7)) @@ -34,7 +35,7 @@ type C = ObjectHasKey<[string, number], '2'>; // "false" type D = A<[string]>; // "true" >D : Symbol(D, Decl(deferredLookupTypeResolution2.ts, 9, 45)) ->A : Symbol(A, Decl(deferredLookupTypeResolution2.ts, 4, 68)) +>A : Symbol(A, Decl(deferredLookupTypeResolution2.ts, 4, 85)) // Error, "false" not handled type E = { true: 'true' }[ObjectHasKey]; diff --git a/tests/baselines/reference/deferredLookupTypeResolution2.types b/tests/baselines/reference/deferredLookupTypeResolution2.types index 76354731097..88994722a2e 100644 --- a/tests/baselines/reference/deferredLookupTypeResolution2.types +++ b/tests/baselines/reference/deferredLookupTypeResolution2.types @@ -10,61 +10,62 @@ type StringContains = ({ [K in S]: 'true' } >key : string >L : L -type ObjectHasKey = StringContains; ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +type ObjectHasKey = StringContains, L>; +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] >O : O >L : L >StringContains : ({ [K in S]: "true"; } & { [key: string]: "false"; })[L] +>Extract : Extract >O : O >L : L type A = ObjectHasKey; ->A : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] +>A : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })["0"] >T : T ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] >T : T type B = ObjectHasKey<[string, number], '1'>; // "true" >B : "true" ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] type C = ObjectHasKey<[string, number], '2'>; // "false" >C : "false" ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] type D = A<[string]>; // "true" >D : "true" ->A : ({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["0"] +>A : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })["0"] // Error, "false" not handled type E = { true: 'true' }[ObjectHasKey]; ->E : { true: "true"; }[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] +>E : { true: "true"; }[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]] >T : T >true : "true" ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] >T : T type Juxtapose = ({ true: 'otherwise' } & { [k: string]: 'true' })[ObjectHasKey]; ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]] >T : T >true : "otherwise" >k : string ->ObjectHasKey : ({ [K in keyof O]: "true"; } & { [key: string]: "false"; })[L] +>ObjectHasKey : ({ [K in Extract]: "true"; } & { [key: string]: "false"; })[L] >T : T // Error, "otherwise" is missing type DeepError = { true: 'true' }[Juxtapose]; ->DeepError : { true: "true"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]] +>DeepError : { true: "true"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]]] >T : T >true : "true" ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]] >T : T type DeepOK = { true: 'true', otherwise: 'false' }[Juxtapose]; ->DeepOK : { true: "true"; otherwise: "false"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]]] +>DeepOK : { true: "true"; otherwise: "false"; }[({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]]] >T : T >true : "true" >otherwise : "false" ->Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in keyof T]: "true"; } & { [key: string]: "false"; })["1"]] +>Juxtapose : ({ true: "otherwise"; } & { [k: string]: "true"; })[({ [K in Extract]: "true"; } & { [key: string]: "false"; })["1"]] >T : T diff --git a/tests/baselines/reference/for-inStatements.errors.txt b/tests/baselines/reference/for-inStatements.errors.txt index 2ae4cdb79f0..50f31d669cd 100644 --- a/tests/baselines/reference/for-inStatements.errors.txt +++ b/tests/baselines/reference/for-inStatements.errors.txt @@ -1,5 +1,5 @@ -tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(33,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'. -tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(50,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'. +tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(33,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'Extract'. +tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(50,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'Extract'. tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(79,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'Color.Blue'. @@ -38,7 +38,7 @@ tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(79,15): for (var x in this.biz) { } for (var x in this) { } ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'. +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'Extract'. return null; } @@ -57,7 +57,7 @@ tests/cases/conformance/statements/for-inStatements/for-inStatements.ts(79,15): for (var x in this.biz) { } for (var x in this) { } ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'. +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'Extract'. for (var x in super.biz) { } for (var x in super.biz()) { } diff --git a/tests/baselines/reference/for-inStatementsInvalid.errors.txt b/tests/baselines/reference/for-inStatementsInvalid.errors.txt index 3d7dd1c79f3..8e1bb29d083 100644 --- a/tests/baselines/reference/for-inStatementsInvalid.errors.txt +++ b/tests/baselines/reference/for-inStatementsInvalid.errors.txt @@ -9,10 +9,10 @@ tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(1 tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(20,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'string'. tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(22,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'string'. tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(29,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'number'. -tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(31,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'. +tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(31,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'Extract'. tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(38,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'number'. tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(46,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'number'. -tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(48,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'. +tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(48,18): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'Extract'. tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(51,23): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'number'. tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(62,15): error TS2407: The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type 'number'. @@ -72,7 +72,7 @@ tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(6 for (var x in this.biz) { } for (var x in this) { } ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'. +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'Extract'. return null; } @@ -95,7 +95,7 @@ tests/cases/conformance/statements/for-inStatements/for-inStatementsInvalid.ts(6 for (var x in this.biz) { } for (var x in this) { } ~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'keyof this'. +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'string', but here has type 'Extract'. for (var x in super.biz) { } for (var x in super.biz()) { } diff --git a/tests/baselines/reference/forInStatement3.types b/tests/baselines/reference/forInStatement3.types index 09e6cf3ad96..9fe63651f55 100644 --- a/tests/baselines/reference/forInStatement3.types +++ b/tests/baselines/reference/forInStatement3.types @@ -8,7 +8,7 @@ function F() { >T : T for (var a in expr) { ->a : keyof T +>a : Extract >expr : T } } diff --git a/tests/baselines/reference/implicitAnyInCatch.types b/tests/baselines/reference/implicitAnyInCatch.types index 93cce09928e..6f70165407f 100644 --- a/tests/baselines/reference/implicitAnyInCatch.types +++ b/tests/baselines/reference/implicitAnyInCatch.types @@ -22,7 +22,7 @@ class C { >temp : () => void for (var x in this) { ->x : keyof this +>x : Extract >this : this } } diff --git a/tests/baselines/reference/inOperatorWithGeneric.types b/tests/baselines/reference/inOperatorWithGeneric.types index eba9bf1419b..dd373d8e075 100644 --- a/tests/baselines/reference/inOperatorWithGeneric.types +++ b/tests/baselines/reference/inOperatorWithGeneric.types @@ -9,7 +9,7 @@ class C { >T : T for (var p in x) { ->p : keyof T +>p : Extract >x : T } } diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.js b/tests/baselines/reference/indexedAccessRetainsIndexSignature.js index 1b77b95527b..92952515779 100644 --- a/tests/baselines/reference/indexedAccessRetainsIndexSignature.js +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.js @@ -1,5 +1,5 @@ //// [indexedAccessRetainsIndexSignature.ts] -type Diff = +type Diff = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] type Omit = Pick> type Omit1 = Pick>; diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols b/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols index 9858f6fc162..ad46c367ba6 100644 --- a/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.symbols @@ -1,15 +1,15 @@ === tests/cases/compiler/indexedAccessRetainsIndexSignature.ts === -type Diff = +type Diff = >Diff : Symbol(Diff, Decl(indexedAccessRetainsIndexSignature.ts, 0, 0)) >T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 0, 10)) ->U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 0, 27)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 0, 30)) ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T] >P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 1, 8)) >T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 0, 10)) >P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 1, 8)) >P : Symbol(P, Decl(indexedAccessRetainsIndexSignature.ts, 1, 26)) ->U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 0, 27)) +>U : Symbol(U, Decl(indexedAccessRetainsIndexSignature.ts, 0, 30)) >x : Symbol(x, Decl(indexedAccessRetainsIndexSignature.ts, 1, 48)) >T : Symbol(T, Decl(indexedAccessRetainsIndexSignature.ts, 0, 10)) diff --git a/tests/baselines/reference/indexedAccessRetainsIndexSignature.types b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types index 8dcbe9bf218..5334cf891df 100644 --- a/tests/baselines/reference/indexedAccessRetainsIndexSignature.types +++ b/tests/baselines/reference/indexedAccessRetainsIndexSignature.types @@ -1,5 +1,5 @@ === tests/cases/compiler/indexedAccessRetainsIndexSignature.ts === -type Diff = +type Diff = >Diff : ({ [P in T]: P; } & { [P in U]: never; } & { [x: string]: never; })[T] >T : T >U : U diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index ec2126f438d..e2db782d788 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -125,14 +125,14 @@ interface P { } type NonIndexableUnion2 = string | number; ->NonIndexableUnion2 : string | number +>NonIndexableUnion2 : NonIndexableUnion2 interface Q { >Q : Q [u: NonIndexableUnion2]: A; ->u : string | number ->NonIndexableUnion2 : string | number +>u : NonIndexableUnion2 +>NonIndexableUnion2 : NonIndexableUnion2 >A : A } diff --git a/tests/baselines/reference/inferTypes1.errors.txt b/tests/baselines/reference/inferTypes1.errors.txt index 01907bdc95b..4684b8f5e34 100644 --- a/tests/baselines/reference/inferTypes1.errors.txt +++ b/tests/baselines/reference/inferTypes1.errors.txt @@ -17,7 +17,8 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS2304: C tests/cases/conformance/types/conditional/inferTypes1.ts(75,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'. tests/cases/conformance/types/conditional/inferTypes1.ts(82,44): error TS2344: Type 'U' does not satisfy the constraint 'string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'. + Type 'T' is not assignable to type 'symbol'. ==== tests/cases/conformance/types/conditional/inferTypes1.ts (16 errors) ==== @@ -200,7 +201,8 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(144,40): error TS2322: type A = T extends string ? { [P in T]: void; } : T; type B = string extends T ? { [P in T]: void; } : T; // Error ~ -!!! error TS2322: Type 'T' is not assignable to type 'string'. +!!! error TS2322: Type 'T' is not assignable to type 'string | number | symbol'. +!!! error TS2322: Type 'T' is not assignable to type 'symbol'. // Repro from #22302 diff --git a/tests/baselines/reference/isomorphicMappedTypeInference.types b/tests/baselines/reference/isomorphicMappedTypeInference.types index b24bb071eeb..d0db5608b6f 100644 --- a/tests/baselines/reference/isomorphicMappedTypeInference.types +++ b/tests/baselines/reference/isomorphicMappedTypeInference.types @@ -64,19 +64,19 @@ function boxify(obj: T): Boxified { >T : T for (let k in obj) { ->k : keyof T +>k : Extract >obj : T result[k] = box(obj[k]); ->result[k] = box(obj[k]) : Box ->result[k] : Boxified[keyof T] +>result[k] = box(obj[k]) : Box]> +>result[k] : Boxified[Extract] >result : Boxified ->k : keyof T ->box(obj[k]) : Box +>k : Extract +>box(obj[k]) : Box]> >box : (x: T) => Box ->obj[k] : T[keyof T] +>obj[k] : T[Extract] >obj : T ->k : keyof T +>k : Extract } return result; >result : Boxified @@ -97,19 +97,19 @@ function unboxify(obj: Boxified): T { >T : T for (let k in obj) { ->k : keyof T +>k : Extract >obj : Boxified result[k] = unbox(obj[k]); ->result[k] = unbox(obj[k]) : T[keyof T] ->result[k] : T[keyof T] +>result[k] = unbox(obj[k]) : T[Extract] +>result[k] : T[Extract] >result : T ->k : keyof T ->unbox(obj[k]) : T[keyof T] +>k : Extract +>unbox(obj[k]) : T[Extract] >unbox : (x: Box) => T ->obj[k] : Boxified[keyof T] +>obj[k] : Boxified[Extract] >obj : Boxified ->k : keyof T +>k : Extract } return result; >result : T @@ -125,19 +125,19 @@ function assignBoxified(obj: Boxified, values: T) { >T : T for (let k in values) { ->k : keyof T +>k : Extract >values : T obj[k].value = values[k]; ->obj[k].value = values[k] : T[keyof T] ->obj[k].value : T[keyof T] ->obj[k] : Boxified[keyof T] +>obj[k].value = values[k] : T[Extract] +>obj[k].value : T[Extract] +>obj[k] : Boxified[Extract] >obj : Boxified ->k : keyof T ->value : T[keyof T] ->values[k] : T[keyof T] +>k : Extract +>value : T[Extract] +>values[k] : T[Extract] >values : T ->k : keyof T +>k : Extract } } diff --git a/tests/baselines/reference/keyofAndForIn.types b/tests/baselines/reference/keyofAndForIn.types index c4997c05bfe..9de1b651843 100644 --- a/tests/baselines/reference/keyofAndForIn.types +++ b/tests/baselines/reference/keyofAndForIn.types @@ -33,14 +33,14 @@ function f1(obj: { [P in K]: T }, k: K) { >k1 : K } for (let k2 in obj) { ->k2 : K +>k2 : Extract >obj : { [P in K]: T; } let x2 = obj[k2]; ->x2 : { [P in K]: T; }[K] ->obj[k2] : { [P in K]: T; }[K] +>x2 : { [P in K]: T; }[Extract] +>obj[k2] : { [P in K]: T; }[Extract] >obj : { [P in K]: T; } ->k2 : K +>k2 : Extract } } @@ -76,14 +76,14 @@ function f2(obj: { [P in keyof T]: T[P] }, k: keyof T) { >k1 : keyof T } for (let k2 in obj) { ->k2 : keyof T +>k2 : Extract >obj : { [P in keyof T]: T[P]; } let x2 = obj[k2]; ->x2 : { [P in keyof T]: T[P]; }[keyof T] ->obj[k2] : { [P in keyof T]: T[P]; }[keyof T] +>x2 : { [P in keyof T]: T[P]; }[Extract] +>obj[k2] : { [P in keyof T]: T[P]; }[Extract] >obj : { [P in keyof T]: T[P]; } ->k2 : keyof T +>k2 : Extract } } @@ -121,13 +121,13 @@ function f3(obj: { [P in K]: T[P] }, k: K) { >k1 : K } for (let k2 in obj) { ->k2 : K +>k2 : Extract >obj : { [P in K]: T[P]; } let x2 = obj[k2]; ->x2 : { [P in K]: T[P]; }[K] ->obj[k2] : { [P in K]: T[P]; }[K] +>x2 : { [P in K]: T[P]; }[Extract] +>obj[k2] : { [P in K]: T[P]; }[Extract] >obj : { [P in K]: T[P]; } ->k2 : K +>k2 : Extract } } diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 1ee6bfc218b..70f1c8b856e 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -554,7 +554,7 @@ class AnotherSampleClass extends SampleClass { new AnotherSampleClass({}); // Positive repro from #17166 -function f3(t: T, k: K, tk: T[K]): void { +function f3>(t: T, k: K, tk: T[K]): void { for (let key in t) { key = k // ok, K ==> keyof T t[key] = tk; // ok, T[K] ==> T[keyof T] @@ -1208,7 +1208,7 @@ declare class AnotherSampleClass extends SampleClass { constructor(props: T); brokenMethod(): void; } -declare function f3(t: T, k: K, tk: T[K]): void; +declare function f3>(t: T, k: K, tk: T[K]): void; declare type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]; }; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index c1a3449991f..1d59deb12b3 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -1963,31 +1963,32 @@ new AnotherSampleClass({}); >AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 540, 54)) // Positive repro from #17166 -function f3(t: T, k: K, tk: T[K]): void { +function f3>(t: T, k: K, tk: T[K]): void { >f3 : Symbol(f3, Decl(keyofAndIndexedAccess.ts, 552, 27)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12)) >K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12)) ->t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 51)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12)) ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 39)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 56)) >K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 45)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 62)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12)) >K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14)) for (let key in t) { >key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12)) ->t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 51)) key = k // ok, K ==> keyof T >key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12)) ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 39)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 56)) t[key] = tk; // ok, T[K] ==> T[keyof T] ->t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 51)) >key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 45)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 62)) } } diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 694abf7d10e..462dde9ca03 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -59,10 +59,10 @@ const enum E { A, B, C } >C : E.C type K00 = keyof any; // string ->K00 : string +>K00 : string | number | symbol type K01 = keyof string; // "toString" | "charAt" | ... ->K01 : "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" +>K01 : number | "length" | "toString" | "concat" | "slice" | "indexOf" | "lastIndexOf" | "charAt" | "charCodeAt" | "localeCompare" | "match" | "replace" | "search" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | "valueOf" type K02 = keyof number; // "toString" | "toFixed" | "toExponential" | ... >K02 : "toString" | "toLocaleString" | "valueOf" | "toFixed" | "toExponential" | "toPrecision" @@ -88,11 +88,11 @@ type K10 = keyof Shape; // "name" | "width" | "height" | "visible" >Shape : Shape type K11 = keyof Shape[]; // "length" | "toString" | ... ->K11 : "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight" +>K11 : number | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight" >Shape : Shape type K12 = keyof Dictionary; // string ->K12 : string +>K12 : string | number | symbol >Dictionary : Dictionary >Shape : Shape @@ -108,7 +108,7 @@ type K15 = keyof E; // "toString" | "toFixed" | "toExponential" | ... >E : E type K16 = keyof [string, number]; // "0" | "1" | "length" | "toString" | ... ->K16 : "0" | "1" | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight" +>K16 : number | "0" | "1" | "length" | "toString" | "toLocaleString" | "push" | "pop" | "concat" | "join" | "reverse" | "shift" | "slice" | "sort" | "splice" | "unshift" | "indexOf" | "lastIndexOf" | "every" | "some" | "forEach" | "map" | "filter" | "reduce" | "reduceRight" type K17 = keyof (Shape | Item); // "name" >K17 : "name" @@ -121,7 +121,7 @@ type K18 = keyof (Shape & Item); // "name" | "width" | "height" | "visible" | " >Item : Item type K19 = keyof NumericallyIndexed // never ->K19 : never +>K19 : number >NumericallyIndexed : NumericallyIndexed >Shape : Shape @@ -136,7 +136,7 @@ type K20 = KeyOf; // "name" | "width" | "height" | "visible" >Shape : Shape type K21 = KeyOf>; // string ->K21 : string +>K21 : string | number | symbol >KeyOf : keyof T >Dictionary : Dictionary >Shape : Shape @@ -825,7 +825,7 @@ function f54(obj: T, key: keyof T) { >T : T for (let s in obj[key]) { ->s : keyof T[keyof T] +>s : Extract >obj[key] : T[keyof T] >obj : T >key : keyof T @@ -850,7 +850,7 @@ function f55(obj: T, key: K) { >K : K for (let s in obj[key]) { ->s : keyof T[K] +>s : Extract >obj[key] : T[K] >obj : T >key : K @@ -873,17 +873,17 @@ function f60(source: T, target: T) { >T : T for (let k in source) { ->k : keyof T +>k : Extract >source : T target[k] = source[k]; ->target[k] = source[k] : T[keyof T] ->target[k] : T[keyof T] +>target[k] = source[k] : T[Extract] +>target[k] : T[Extract] >target : T ->k : keyof T ->source[k] : T[keyof T] +>k : Extract +>source[k] : T[Extract] >source : T ->k : keyof T +>k : Extract } } @@ -2295,10 +2295,11 @@ new AnotherSampleClass({}); >{} : {} // Positive repro from #17166 -function f3(t: T, k: K, tk: T[K]): void { ->f3 : (t: T, k: K, tk: T[K]) => void +function f3>(t: T, k: K, tk: T[K]): void { +>f3 : >(t: T, k: K, tk: T[K]) => void >T : T >K : K +>Extract : Extract >T : T >t : T >T : T @@ -2309,19 +2310,19 @@ function f3(t: T, k: K, tk: T[K]): void { >K : K for (let key in t) { ->key : keyof T +>key : Extract >t : T key = k // ok, K ==> keyof T >key = k : K ->key : keyof T +>key : Extract >k : K t[key] = tk; // ok, T[K] ==> T[keyof T] >t[key] = tk : T[K] ->t[key] : T[keyof T] +>t[key] : T[Extract] >t : T ->key : keyof T +>key : Extract >tk : T[K] } } diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 44b8b4a6051..f9bb63c43b1 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -28,19 +28,22 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof (T | U)'. Type 'keyof T' is not assignable to type 'keyof (T | U)'. - Type 'string' is not assignable to type 'keyof (T | U)'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,9): error TS2322: Type 'keyof T' is not assignable to type 'K'. - Type 'string' is not assignable to type 'K'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(88,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. - Type 'keyof T' is not assignable to type 'K'. + Type 'string | number | symbol' is not assignable to type 'keyof (T | U)'. + Type 'string' is not assignable to type 'keyof (T | U)'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,9): error TS2322: Type 'Extract' is not assignable to type 'K'. + Type 'string & keyof T' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(88,9): error TS2322: Type 'T[Extract]' is not assignable to type 'T[K]'. + Type 'Extract' is not assignable to type 'K'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(91,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(94,5): error TS2322: Type 'T[J]' is not assignable to type 'U[J]'. Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(97,5): error TS2322: Type 'T[K]' is not assignable to type 'T[J]'. Type 'K' is not assignable to type 'J'. - Type 'keyof T' is not assignable to type 'J'. - Type 'string' is not assignable to type 'J'. + Type 'Extract' is not assignable to type 'J'. + Type 'string & keyof T' is not assignable to type 'J'. + Type 'string' is not assignable to type 'J'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'. Type 'T' is not assignable to type 'U'. @@ -178,24 +181,26 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error ~~ !!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof (T | U)'. !!! error TS2322: Type 'keyof T' is not assignable to type 'keyof (T | U)'. -!!! error TS2322: Type 'string' is not assignable to type 'keyof (T | U)'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof (T | U)'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof (T | U)'. k2 = k1; } // Repro from #17166 - function f3( + function f3, U extends T, J extends K>( t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void { for (let key in t) { key = k // ok, K ==> keyof T k = key // error, keyof T =/=> K ~ -!!! error TS2322: Type 'keyof T' is not assignable to type 'K'. -!!! error TS2322: Type 'string' is not assignable to type 'K'. +!!! error TS2322: Type 'Extract' is not assignable to type 'K'. +!!! error TS2322: Type 'string & keyof T' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. t[key] = tk; // ok, T[K] ==> T[keyof T] tk = t[key]; // error, T[keyof T] =/=> T[K] ~~ -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'K'. +!!! error TS2322: Type 'T[Extract]' is not assignable to type 'T[K]'. +!!! error TS2322: Type 'Extract' is not assignable to type 'K'. } tk = uk; uk = tk; // error @@ -214,8 +219,9 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error ~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'T[J]'. !!! error TS2322: Type 'K' is not assignable to type 'J'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'J'. -!!! error TS2322: Type 'string' is not assignable to type 'J'. +!!! error TS2322: Type 'Extract' is not assignable to type 'J'. +!!! error TS2322: Type 'string & keyof T' is not assignable to type 'J'. +!!! error TS2322: Type 'string' is not assignable to type 'J'. tk = uj; uj = tk; // error diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.js b/tests/baselines/reference/keyofAndIndexedAccessErrors.js index d267699ffd6..0f026d5d2e5 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.js +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.js @@ -80,7 +80,7 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { } // Repro from #17166 -function f3( +function f3, U extends T, J extends K>( t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void { for (let key in t) { key = k // ok, K ==> keyof T diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols index 47b22af2541..d062677fa02 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols @@ -270,18 +270,19 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { } // Repro from #17166 -function f3( +function f3, U extends T, J extends K>( >f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 78, 1)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) >K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46)) +>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63)) >K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void { ->t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60)) +>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) >k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9)) >K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) @@ -289,22 +290,22 @@ function f3( >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) >K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) >u : Symbol(u, Decl(keyofAndIndexedAccessErrors.ts, 82, 25)) ->U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50)) >j : Symbol(j, Decl(keyofAndIndexedAccessErrors.ts, 82, 31)) ->J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46)) +>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63)) >uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37)) ->U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50)) >K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) >tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46)) +>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63)) >uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57)) ->U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33)) ->J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50)) +>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63)) for (let key in t) { >key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) ->t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60)) +>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77)) key = k // ok, K ==> keyof T >key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) @@ -315,13 +316,13 @@ function f3( >key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) t[key] = tk; // ok, T[K] ==> T[keyof T] ->t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60)) +>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77)) >key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) >tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) tk = t[key]; // error, T[keyof T] =/=> T[K] >tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) ->t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60)) +>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77)) >key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) } tk = uk; diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index bcd3878013d..2f50ef5c53c 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -22,7 +22,7 @@ type Dictionary = { [x: string]: T }; >T : T type T00 = keyof K0; // Error ->T00 : string +>T00 : string | number | symbol >K0 : No type information available! type T01 = keyof Object; @@ -30,23 +30,23 @@ type T01 = keyof Object; >Object : Object type T02 = keyof keyof Object; ->T02 : "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T02 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" >Object : Object type T03 = keyof keyof keyof Object; ->T03 : "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T03 : "toString" | "toLocaleString" | "valueOf" >Object : Object type T04 = keyof keyof keyof keyof Object; ->T04 : "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" >Object : Object type T05 = keyof keyof keyof keyof keyof Object; ->T05 : "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T05 : "toString" | "toLocaleString" | "valueOf" >Object : Object type T06 = keyof keyof keyof keyof keyof keyof Object; ->T06 : "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" >Object : Object type T10 = Shape["name"]; @@ -301,10 +301,11 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { } // Repro from #17166 -function f3( ->f3 : (t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]) => void +function f3, U extends T, J extends K>( +>f3 : , U extends T, J extends K>(t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]) => void >T : T >K : K +>Extract : Extract >T : T >U : U >T : T @@ -334,32 +335,32 @@ function f3( >J : J for (let key in t) { ->key : keyof T +>key : Extract >t : T key = k // ok, K ==> keyof T >key = k : K ->key : keyof T +>key : Extract >k : K k = key // error, keyof T =/=> K ->k = key : keyof T +>k = key : Extract >k : K ->key : keyof T +>key : Extract t[key] = tk; // ok, T[K] ==> T[keyof T] >t[key] = tk : T[K] ->t[key] : T[keyof T] +>t[key] : T[Extract] >t : T ->key : keyof T +>key : Extract >tk : T[K] tk = t[key]; // error, T[keyof T] =/=> T[K] ->tk = t[key] : T[keyof T] +>tk = t[key] : T[Extract] >tk : T[K] ->t[key] : T[keyof T] +>t[key] : T[Extract] >t : T ->key : keyof T +>key : Extract } tk = uk; >tk = uk : U[K] diff --git a/tests/baselines/reference/lateBoundConstraintTypeChecksCorrectly.errors.txt b/tests/baselines/reference/lateBoundConstraintTypeChecksCorrectly.errors.txt deleted file mode 100644 index d9d573e0ab9..00000000000 --- a/tests/baselines/reference/lateBoundConstraintTypeChecksCorrectly.errors.txt +++ /dev/null @@ -1,29 +0,0 @@ -tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts(17,16): error TS2536: Type 'unique symbol' cannot be used to index type 'T'. -tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts(18,17): error TS2536: Type 'unique symbol' cannot be used to index type 'T'. - - -==== tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts (2 errors) ==== - declare const fooProp: unique symbol; - declare const barProp: unique symbol; - - type BothProps = typeof fooProp | typeof barProp; - - export interface Foo { - [fooProp]: T; - [barProp]: string; - } - - function f>(x: T) { - const abc = x[fooProp]; // expected: 'T[typeof fooProp]' - - /** - * Expected: no error - */ - const def: T[typeof fooProp] = x[fooProp]; - ~~~~~~~~~~~~~~~~~ -!!! error TS2536: Type 'unique symbol' cannot be used to index type 'T'. - const def2: T[typeof barProp] = x[barProp]; - ~~~~~~~~~~~~~~~~~ -!!! error TS2536: Type 'unique symbol' cannot be used to index type 'T'. - } - \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeErrors.errors.txt b/tests/baselines/reference/mappedTypeErrors.errors.txt index 3245f9932f0..f78c32531a4 100644 --- a/tests/baselines/reference/mappedTypeErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeErrors.errors.txt @@ -1,7 +1,8 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(19,20): error TS2313: Type parameter 'P' has a circular constraint. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(20,20): error TS2322: Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(21,20): error TS2322: Type 'Date' is not assignable to type 'string'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(22,19): error TS2344: Type 'Date' does not satisfy the constraint 'string'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(21,20): error TS2322: Type 'Date' is not assignable to type 'string | number | symbol'. + Type 'Date' is not assignable to type 'symbol'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(22,19): error TS2344: Type 'Date' does not satisfy the constraint 'string | number | symbol'. + Type 'Date' is not assignable to type 'symbol'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(25,24): error TS2344: Type '"foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(26,24): error TS2344: Type '"name" | "foo"' does not satisfy the constraint '"name" | "width" | "height" | "visible"'. Type '"foo"' is not assignable to type '"name" | "width" | "height" | "visible"'. @@ -45,11 +46,12 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(129,5): error TS2322: T tests/cases/conformance/types/mapped/mappedTypeErrors.ts(130,5): error TS2322: Type '{ a: string; }' is not assignable to type '{ [x: string]: any; a?: number | undefined; }'. Types of property 'a' are incompatible. Type 'string' is not assignable to type 'number | undefined'. -tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,16): error TS2322: Type 'T' is not assignable to type 'string'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,16): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'. + Type 'T' is not assignable to type 'symbol'. tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,21): error TS2536: Type 'P' cannot be used to index type 'T'. -==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (26 errors) ==== +==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (25 errors) ==== interface Shape { name: string; width: number; @@ -72,14 +74,14 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,21): error TS2536: ~ !!! error TS2313: Type parameter 'P' has a circular constraint. type T01 = { [P in number]: string }; // Error - ~~~~~~ -!!! error TS2322: Type 'number' is not assignable to type 'string'. type T02 = { [P in Date]: number }; // Error ~~~~ -!!! error TS2322: Type 'Date' is not assignable to type 'string'. +!!! error TS2322: Type 'Date' is not assignable to type 'string | number | symbol'. +!!! error TS2322: Type 'Date' is not assignable to type 'symbol'. type T03 = Record; // Error ~~~~ -!!! error TS2344: Type 'Date' does not satisfy the constraint 'string'. +!!! error TS2344: Type 'Date' does not satisfy the constraint 'string | number | symbol'. +!!! error TS2344: Type 'Date' is not assignable to type 'symbol'. type T10 = Pick; type T11 = Pick; // Error @@ -258,7 +260,8 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(136,21): error TS2536: pf: {[P in F]?: T[P]}, pt: {[P in T]?: T[P]}, // note: should be in keyof T ~ -!!! error TS2322: Type 'T' is not assignable to type 'string'. +!!! error TS2322: Type 'T' is not assignable to type 'string | number | symbol'. +!!! error TS2322: Type 'T' is not assignable to type 'symbol'. ~~~~ !!! error TS2536: Type 'P' cannot be used to index type 'T'. }; diff --git a/tests/baselines/reference/mappedTypeErrors.types b/tests/baselines/reference/mappedTypeErrors.types index ab0ae55a0e1..3faae85af8b 100644 --- a/tests/baselines/reference/mappedTypeErrors.types +++ b/tests/baselines/reference/mappedTypeErrors.types @@ -373,17 +373,17 @@ function setState(obj: T, props: Pick) { >K : K for (let k in props) { ->k : K +>k : Extract >props : Pick obj[k] = props[k]; ->obj[k] = props[k] : Pick[K] ->obj[k] : T[K] +>obj[k] = props[k] : Pick[Extract] +>obj[k] : T[Extract] >obj : T ->k : K ->props[k] : Pick[K] +>k : Extract +>props[k] : Pick[Extract] >props : Pick ->k : K +>k : Extract } } @@ -468,19 +468,19 @@ class C { >K : K for (let k in props) { ->k : K +>k : Extract >props : Pick this.state[k] = props[k]; ->this.state[k] = props[k] : Pick[K] ->this.state[k] : T[K] +>this.state[k] = props[k] : Pick[Extract] +>this.state[k] : T[Extract] >this.state : T >this : this >state : T ->k : K ->props[k] : Pick[K] +>k : Extract +>props[k] : Pick[Extract] >props : Pick ->k : K +>k : Extract } } } diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index ee49ef12283..26618cc15db 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -43,16 +43,20 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(143,5): error TS Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(148,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. Type 'keyof U' is not assignable to type 'keyof T'. - Type 'string' is not assignable to type 'keyof T'. + Type 'string | number | symbol' is not assignable to type 'keyof T'. + Type 'string' is not assignable to type 'keyof T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(153,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: T[P]; }'. Type 'keyof T' is not assignable to type 'K'. - Type 'string' is not assignable to type 'K'. + Type 'string | number | symbol' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(158,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. Type 'keyof U' is not assignable to type 'K'. - Type 'string' is not assignable to type 'K'. + Type 'string | number | symbol' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(163,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. Type 'keyof T' is not assignable to type 'K'. - Type 'string' is not assignable to type 'K'. + Type 'string | number | symbol' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. Type 'T' is not assignable to type 'U'. @@ -276,7 +280,8 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. !!! error TS2322: Type 'keyof U' is not assignable to type 'keyof T'. -!!! error TS2322: Type 'string' is not assignable to type 'keyof T'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof T'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof T'. } function f73(x: { [P in K]: T[P] }, y: { [P in keyof T]: T[P] }) { @@ -285,7 +290,8 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: T[P]; }'. !!! error TS2322: Type 'keyof T' is not assignable to type 'K'. -!!! error TS2322: Type 'string' is not assignable to type 'K'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. } function f74(x: { [P in K]: T[P] }, y: { [P in keyof U]: U[P] }) { @@ -294,7 +300,8 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. !!! error TS2322: Type 'keyof U' is not assignable to type 'K'. -!!! error TS2322: Type 'string' is not assignable to type 'K'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. } function f75(x: { [P in K]: T[P] }, y: { [P in keyof T]: U[P] }) { @@ -303,7 +310,8 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. !!! error TS2322: Type 'keyof T' is not assignable to type 'K'. -!!! error TS2322: Type 'string' is not assignable to type 'K'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. } function f76(x: { [P in K]: T[P] }, y: { [P in K]: U[P] }) { diff --git a/tests/baselines/reference/mappedTypeWithAny.types b/tests/baselines/reference/mappedTypeWithAny.types index 36fad9140cc..6bf62c9730c 100644 --- a/tests/baselines/reference/mappedTypeWithAny.types +++ b/tests/baselines/reference/mappedTypeWithAny.types @@ -11,7 +11,7 @@ type ItemMap = { [P in keyof T]: Item }; >Item : Item declare let x0: keyof any; ->x0 : string +>x0 : string | number | symbol declare let x1: { [P in any]: Item }; >x1 : { [x: string]: Item; } diff --git a/tests/baselines/reference/mappedTypes4.types b/tests/baselines/reference/mappedTypes4.types index c003765d517..7292e143b42 100644 --- a/tests/baselines/reference/mappedTypes4.types +++ b/tests/baselines/reference/mappedTypes4.types @@ -40,19 +40,19 @@ function boxify(obj: T): Boxified { >T : T for (let k in obj) { ->k : keyof T +>k : Extract >obj : T result[k] = { value: obj[k] }; ->result[k] = { value: obj[k] } : { value: T[keyof T]; } ->result[k] : Boxified[keyof T] +>result[k] = { value: obj[k] } : { value: T[Extract]; } +>result[k] : Boxified[Extract] >result : Boxified ->k : keyof T ->{ value: obj[k] } : { value: T[keyof T]; } ->value : T[keyof T] ->obj[k] : T[keyof T] +>k : Extract +>{ value: obj[k] } : { value: T[Extract]; } +>value : T[Extract] +>obj[k] : T[Extract] >obj : T ->k : keyof T +>k : Extract } return result; >result : Boxified diff --git a/tests/baselines/reference/neverUnionIntersection.types b/tests/baselines/reference/neverUnionIntersection.types index 5d9085e72e6..4f578052e9c 100644 --- a/tests/baselines/reference/neverUnionIntersection.types +++ b/tests/baselines/reference/neverUnionIntersection.types @@ -6,7 +6,7 @@ type T02 = string & never; >T02 : never type T03 = string | number | never; ->T03 : string | number +>T03 : T03 type T04 = string & number & never; >T04 : never diff --git a/tests/baselines/reference/recursiveTypeRelations.errors.txt b/tests/baselines/reference/recursiveTypeRelations.errors.txt index f29d5742185..8c5596958c3 100644 --- a/tests/baselines/reference/recursiveTypeRelations.errors.txt +++ b/tests/baselines/reference/recursiveTypeRelations.errors.txt @@ -6,7 +6,7 @@ tests/cases/compiler/recursiveTypeRelations.ts(27,61): error TS2304: Cannot find ==== tests/cases/compiler/recursiveTypeRelations.ts (3 errors) ==== // Repro from #14896 - type Attributes = { + type Attributes = { [Key in Keys]: string; } diff --git a/tests/baselines/reference/recursiveTypeRelations.js b/tests/baselines/reference/recursiveTypeRelations.js index c477ecf1294..9c0887ab446 100644 --- a/tests/baselines/reference/recursiveTypeRelations.js +++ b/tests/baselines/reference/recursiveTypeRelations.js @@ -1,7 +1,7 @@ //// [recursiveTypeRelations.ts] // Repro from #14896 -type Attributes = { +type Attributes = { [Key in Keys]: string; } diff --git a/tests/baselines/reference/recursiveTypeRelations.symbols b/tests/baselines/reference/recursiveTypeRelations.symbols index 2c940df2487..39032cd2f94 100644 --- a/tests/baselines/reference/recursiveTypeRelations.symbols +++ b/tests/baselines/reference/recursiveTypeRelations.symbols @@ -1,7 +1,7 @@ === tests/cases/compiler/recursiveTypeRelations.ts === // Repro from #14896 -type Attributes = { +type Attributes = { >Attributes : Symbol(Attributes, Decl(recursiveTypeRelations.ts, 0, 0)) >Keys : Symbol(Keys, Decl(recursiveTypeRelations.ts, 2, 16)) diff --git a/tests/baselines/reference/recursiveTypeRelations.types b/tests/baselines/reference/recursiveTypeRelations.types index ce6d007d066..b844031c0d1 100644 --- a/tests/baselines/reference/recursiveTypeRelations.types +++ b/tests/baselines/reference/recursiveTypeRelations.types @@ -1,7 +1,7 @@ === tests/cases/compiler/recursiveTypeRelations.ts === // Repro from #14896 -type Attributes = { +type Attributes = { >Attributes : { [Key in Keys]: string; } >Keys : Keys diff --git a/tests/baselines/reference/typeGuardsTypeParameters.types b/tests/baselines/reference/typeGuardsTypeParameters.types index 13fb9965235..c508c92a979 100644 --- a/tests/baselines/reference/typeGuardsTypeParameters.types +++ b/tests/baselines/reference/typeGuardsTypeParameters.types @@ -80,19 +80,19 @@ function fun(item: { [P in keyof T]: T[P] }) { >[] : never[] for (const key in item) { ->key : keyof T +>key : Extract >item : { [P in keyof T]: T[P]; } const value = item[key]; ->value : { [P in keyof T]: T[P]; }[keyof T] ->item[key] : { [P in keyof T]: T[P]; }[keyof T] +>value : { [P in keyof T]: T[P]; }[Extract] +>item[key] : { [P in keyof T]: T[P]; }[Extract] >item : { [P in keyof T]: T[P]; } ->key : keyof T +>key : Extract if (typeof value === "string") { >typeof value === "string" : boolean >typeof value : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ->value : { [P in keyof T]: T[P]; }[keyof T] +>value : { [P in keyof T]: T[P]; }[Extract] >"string" : "string" strings.push(value); @@ -100,7 +100,7 @@ function fun(item: { [P in keyof T]: T[P] }) { >strings.push : (...items: string[]) => number >strings : string[] >push : (...items: string[]) => number ->value : { [P in keyof T]: T[P]; }[keyof T] & string +>value : { [P in keyof T]: T[P]; }[Extract] & string } } } From 8923eec80a49994a653cd791a578126451a336c4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 9 Apr 2018 15:14:32 -0700 Subject: [PATCH 013/229] Added tests for 'import.meta'. --- .../es2019/importMeta/importMeta.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/cases/conformance/es2019/importMeta/importMeta.ts diff --git a/tests/cases/conformance/es2019/importMeta/importMeta.ts b/tests/cases/conformance/es2019/importMeta/importMeta.ts new file mode 100644 index 00000000000..f23410fc536 --- /dev/null +++ b/tests/cases/conformance/es2019/importMeta/importMeta.ts @@ -0,0 +1,28 @@ + +// @target: esnext +// @lib: es5,dom + +// @Filename: example.ts +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); +})(); + +// @Filename: moduleLookingFile01.ts +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; + +// @Filename: scriptLookingFile01.ts +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; From 9b8670cf9208c2681548b2859957297d268535cc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 9 Apr 2018 15:28:37 -0700 Subject: [PATCH 014/229] Accepted baselines. --- .../baselines/reference/importMeta.errors.txt | 125 ++++++++++++++++++ tests/baselines/reference/importMeta.js | 48 +++++++ tests/baselines/reference/importMeta.symbols | 82 ++++++++++++ tests/baselines/reference/importMeta.types | 111 ++++++++++++++++ 4 files changed, 366 insertions(+) create mode 100644 tests/baselines/reference/importMeta.errors.txt create mode 100644 tests/baselines/reference/importMeta.js create mode 100644 tests/baselines/reference/importMeta.symbols create mode 100644 tests/baselines/reference/importMeta.types diff --git a/tests/baselines/reference/importMeta.errors.txt b/tests/baselines/reference/importMeta.errors.txt new file mode 100644 index 00000000000..498da8efdc1 --- /dev/null +++ b/tests/baselines/reference/importMeta.errors.txt @@ -0,0 +1,125 @@ +error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1135: Argument expression expected. +tests/cases/conformance/es2019/importMeta/example.ts(3,65): error TS1135: Argument expression expected. +tests/cases/conformance/es2019/importMeta/example.ts(3,66): error TS2448: Block-scoped variable 'meta' used before its declaration. +tests/cases/conformance/es2019/importMeta/example.ts(6,9): error TS2451: Cannot redeclare block-scoped variable 'size'. +tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1109: Expression expected. +tests/cases/conformance/es2019/importMeta/example.ts(6,22): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/example.ts(6,27): error TS1005: ',' expected. +tests/cases/conformance/es2019/importMeta/example.ts(6,41): error TS1005: ',' expected. +tests/cases/conformance/es2019/importMeta/example.ts(6,49): error TS1005: ',' expected. +tests/cases/conformance/es2019/importMeta/example.ts(6,50): error TS2451: Cannot redeclare block-scoped variable 'size'. +tests/cases/conformance/es2019/importMeta/example.ts(6,55): error TS1005: ',' expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1109: Expression expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,22): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1109: Expression expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,22): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1109: Expression expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,22): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,29): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,30): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,36): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1109: Expression expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,21): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1109: Expression expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,21): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1109: Expression expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,21): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,28): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,29): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,35): error TS1134: Variable declaration expected. + + +!!! error TS2468: Cannot find global value 'Promise'. +==== tests/cases/conformance/es2019/importMeta/example.ts (12 errors) ==== + // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example + (async () => { + ~~~~~~~~~~~~~ +!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + ~~~~~~ +!!! error TS1135: Argument expression expected. + ~ +!!! error TS1135: Argument expression expected. + ~~~~ +!!! error TS2448: Block-scoped variable 'meta' used before its declaration. + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + ~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'size'. + ~~~~~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS1005: ',' expected. + ~~~~ +!!! error TS2451: Cannot redeclare block-scoped variable 'size'. + ~~ +!!! error TS1005: ',' expected. + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); + })(); + +==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (10 errors) ==== + export let x = import.meta; + ~~~~~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1134: Variable declaration expected. + export let y = import.metal; + ~~~~~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1134: Variable declaration expected. + export let z = import.import.import.malkovich; + ~~~~~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1134: Variable declaration expected. + ~~~~~~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. + ~~~~~~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. + +==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (10 errors) ==== + let globalA = import.meta; + ~~~~~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1134: Variable declaration expected. + let globalB = import.metal; + ~~~~~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1134: Variable declaration expected. + let globalC = import.import.import.malkovich; + ~~~~~~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1134: Variable declaration expected. + ~~~~~~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. + ~~~~~~ +!!! error TS1134: Variable declaration expected. + ~ +!!! error TS1134: Variable declaration expected. + \ No newline at end of file diff --git a/tests/baselines/reference/importMeta.js b/tests/baselines/reference/importMeta.js new file mode 100644 index 00000000000..9391dbc4899 --- /dev/null +++ b/tests/baselines/reference/importMeta.js @@ -0,0 +1,48 @@ +//// [tests/cases/conformance/es2019/importMeta/importMeta.ts] //// + +//// [example.ts] +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); +})(); + +//// [moduleLookingFile01.ts] +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; + +//// [scriptLookingFile01.ts] +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; + + +//// [example.js] +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", meta.url).toString()); + const blob = await response.blob(); + const size = , meta, scriptElement, dataset, size; + || 300; + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + document.body.appendChild(image); +})(); +//// [moduleLookingFile01.js] +export let x = , meta; +export let y = , metal; +export let z = , malkovich; +//// [scriptLookingFile01.js] +let globalA = , meta; +let globalB = , metal; +let globalC = , malkovich; diff --git a/tests/baselines/reference/importMeta.symbols b/tests/baselines/reference/importMeta.symbols new file mode 100644 index 00000000000..cff36047d37 --- /dev/null +++ b/tests/baselines/reference/importMeta.symbols @@ -0,0 +1,82 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Symbol(response, Decl(example.ts, 2, 7)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) +>new URL("../hamsters.jpg", import.meta.url).toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>meta : Symbol(meta, Decl(example.ts, 5, 22)) +>toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --)) + + const blob = await response.blob(); +>blob : Symbol(blob, Decl(example.ts, 3, 7)) +>response.blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) +>response : Symbol(response, Decl(example.ts, 2, 7)) +>blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) + + const size = import.meta.scriptElement.dataset.size || 300; +>size : Symbol(size, Decl(example.ts, 5, 7)) +>meta : Symbol(meta, Decl(example.ts, 5, 22)) +>scriptElement : Symbol(scriptElement, Decl(example.ts, 5, 27)) +>dataset : Symbol(dataset, Decl(example.ts, 5, 41)) +>size : Symbol(size, Decl(example.ts, 5, 49)) + + const image = new Image(); +>image : Symbol(image, Decl(example.ts, 7, 7)) +>Image : Symbol(Image, Decl(lib.dom.d.ts, --, --)) + + image.src = URL.createObjectURL(blob); +>image.src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>URL.createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>blob : Symbol(blob, Decl(example.ts, 3, 7)) + + image.width = image.height = size; +>image.width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image.height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>size : Symbol(size, Decl(example.ts, 5, 7)) + + document.body.appendChild(image); +>document.body.appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>document.body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>document : Symbol(document, Decl(lib.dom.d.ts, --, --)) +>body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10)) +>meta : Symbol(meta, Decl(moduleLookingFile01.ts, 0, 22)) + +export let y = import.metal; +>y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10)) +>metal : Symbol(metal, Decl(moduleLookingFile01.ts, 1, 22)) + +export let z = import.import.import.malkovich; +>z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10)) +>malkovich : Symbol(malkovich, Decl(moduleLookingFile01.ts, 2, 36)) + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3)) +>meta : Symbol(meta, Decl(scriptLookingFile01.ts, 0, 21)) + +let globalB = import.metal; +>globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3)) +>metal : Symbol(metal, Decl(scriptLookingFile01.ts, 1, 21)) + +let globalC = import.import.import.malkovich; +>globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3)) +>malkovich : Symbol(malkovich, Decl(scriptLookingFile01.ts, 2, 35)) + diff --git a/tests/baselines/reference/importMeta.types b/tests/baselines/reference/importMeta.types new file mode 100644 index 00000000000..5004627cb4c --- /dev/null +++ b/tests/baselines/reference/importMeta.types @@ -0,0 +1,111 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);})() : Promise +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);}) : () => Promise +>async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);} : () => Promise + + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Response +>await fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Response +>fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Promise +>fetch : (input?: string | Request, init?: RequestInit) => Promise +>new URL("../hamsters.jpg", import.meta.url).toString() : string +>new URL("../hamsters.jpg", import.meta.url).toString : () => string +>new URL("../hamsters.jpg", import.meta.url) : URL +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; } +>"../hamsters.jpg" : "../hamsters.jpg" +>meta.url : any +>meta : any +>url : any +>toString : () => string + + const blob = await response.blob(); +>blob : Blob +>await response.blob() : Blob +>response.blob() : Promise +>response.blob : () => Promise +>response : Response +>blob : () => Promise + + const size = import.meta.scriptElement.dataset.size || 300; +>size : any +> : any +>meta : any +>scriptElement : any +>dataset : any +>size : any +>|| 300 : any +> : any +>300 : 300 + + const image = new Image(); +>image : HTMLImageElement +>new Image() : HTMLImageElement +>Image : new (width?: number, height?: number) => HTMLImageElement + + image.src = URL.createObjectURL(blob); +>image.src = URL.createObjectURL(blob) : string +>image.src : string +>image : HTMLImageElement +>src : string +>URL.createObjectURL(blob) : string +>URL.createObjectURL : (object: any, options?: ObjectURLOptions) => string +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; } +>createObjectURL : (object: any, options?: ObjectURLOptions) => string +>blob : Blob + + image.width = image.height = size; +>image.width = image.height = size : any +>image.width : number +>image : HTMLImageElement +>width : number +>image.height = size : any +>image.height : number +>image : HTMLImageElement +>height : number +>size : any + + document.body.appendChild(image); +>document.body.appendChild(image) : HTMLImageElement +>document.body.appendChild : (newChild: T) => T +>document.body : HTMLElement +>document : Document +>body : HTMLElement +>appendChild : (newChild: T) => T +>image : HTMLImageElement + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : any +> : any +>meta : any + +export let y = import.metal; +>y : any +> : any +>metal : any + +export let z = import.import.import.malkovich; +>z : any +> : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : any +> : any +>meta : any + +let globalB = import.metal; +>globalB : any +> : any +>metal : any + +let globalC = import.import.import.malkovich; +>globalC : any +> : any +>malkovich : any + From 9e2bbb6f8a9dca00a899ef7eabccbc31bf8aa935 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 9 Apr 2018 17:03:05 -0700 Subject: [PATCH 015/229] Basic parsing/emitting support for 'import.meta'. --- src/compiler/parser.ts | 86 +++++++++++++++++++++++++++++++---------- src/compiler/program.ts | 2 +- src/compiler/types.ts | 29 ++++++++------ 3 files changed, 85 insertions(+), 32 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0b89c3c313c..e9a685d9d26 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -542,7 +542,7 @@ namespace ts { const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import. // We will manually port the flag to the new source file. - newSourceFile.flags |= (sourceFile.flags & NodeFlags.PossiblyContainsDynamicImport); + newSourceFile.flags |= (sourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags); return newSourceFile; } @@ -2627,6 +2627,20 @@ namespace ts { return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken; } + function nextTokenIsDot() { + return nextToken() === SyntaxKind.DotToken; + } + + function nextTokenIsOpenParenOrLessThanOrDot() { + switch (nextToken()) { + case SyntaxKind.OpenParenToken: + case SyntaxKind.LessThanToken: + case SyntaxKind.DotToken: + return true; + } + return false; + } + function parseTypeLiteral(): TypeLiteralNode { const node = createNode(SyntaxKind.TypeLiteral); node.members = parseObjectTypeMembers(); @@ -3095,7 +3109,7 @@ namespace ts { case SyntaxKind.Identifier: return true; case SyntaxKind.ImportKeyword: - return lookAhead(nextTokenIsOpenParenOrLessThan); + return lookAhead(nextTokenIsOpenParenOrLessThanOrDot); default: return isIdentifier(); } @@ -3957,14 +3971,31 @@ namespace ts { // 3)we have a MemberExpression which either completes the LeftHandSideExpression, // or starts the beginning of the first four CallExpression productions. let expression: MemberExpression; - if (token() === SyntaxKind.ImportKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { - // We don't want to eagerly consume all import keyword as import call expression so we look a head to find "(" - // For example: - // var foo3 = require("subfolder - // import * as foo1 from "module-from-node - // We want this import to be a statement rather than import call expression - sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport; - expression = parseTokenNode(); + if (token() === SyntaxKind.ImportKeyword) { + if (lookAhead(nextTokenIsOpenParenOrLessThan)) { + // We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "(" + // For example: + // var foo3 = require("subfolder + // import * as foo1 from "module-from-node + // We want this import to be a statement rather than import call expression + sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport; + expression = parseTokenNode(); + } + else if (lookAhead(nextTokenIsDot)) { + // This is an 'import.*' metaproperty (i.e. 'import.meta') + const fullStart = scanner.getStartPos(); + nextToken(); // advance past the 'import' + nextToken(); // advance past the dot + const node = createNode(SyntaxKind.MetaProperty, fullStart) as MetaProperty; + node.keywordToken = SyntaxKind.ImportKeyword; + node.name = parseIdentifierName(); + expression = finishNode(node); + + sourceFile.flags |= NodeFlags.PossiblyContainsImportMeta; + } + else { + expression = parseMemberExpressionOrHigher(); + } } else { expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher(); @@ -4508,7 +4539,7 @@ namespace ts { case SyntaxKind.FunctionKeyword: return parseFunctionExpression(); case SyntaxKind.NewKeyword: - return parseNewExpression(); + return parseNewExpressionOrNewDotTarget(); case SyntaxKind.SlashToken: case SyntaxKind.SlashEqualsToken: if (reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) { @@ -4659,7 +4690,7 @@ namespace ts { return isIdentifier() ? parseIdentifier() : undefined; } - function parseNewExpression(): NewExpression | MetaProperty { + function parseNewExpressionOrNewDotTarget(): NewExpression | MetaProperty { const fullStart = scanner.getStartPos(); parseExpected(SyntaxKind.NewKeyword); if (parseOptional(SyntaxKind.DotToken)) { @@ -5093,7 +5124,7 @@ namespace ts { return true; case SyntaxKind.ImportKeyword: - return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThan); + return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot); case SyntaxKind.ConstKeyword: case SyntaxKind.ExportKeyword: @@ -6079,14 +6110,29 @@ namespace ts { } function setExternalModuleIndicator(sourceFile: SourceFile) { - sourceFile.externalModuleIndicator = forEach(sourceFile.statements, node => - hasModifier(node, ModifierFlags.Export) - || node.kind === SyntaxKind.ImportEqualsDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference - || node.kind === SyntaxKind.ImportDeclaration - || node.kind === SyntaxKind.ExportAssignment - || node.kind === SyntaxKind.ExportDeclaration + // Usually we'd like to avoid a full tree walk, but it's possible + // that we have a deeper external module indicator (e.g. `import.meta`, + // and possibly nested import statements in the future). + // Ideally the first few statements will be an import/export anyway. + sourceFile.externalModuleIndicator = + !(sourceFile.flags & NodeFlags.PossiblyContainsImportMeta) ? + forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) : + walkTreeForExternalModuleIndicators(sourceFile); + } + + function isAnExternalModuleIndicatorNode(node: Node) { + return hasModifier(node, ModifierFlags.Export) + || node.kind === SyntaxKind.ImportEqualsDeclaration && (node).moduleReference.kind === SyntaxKind.ExternalModuleReference + || node.kind === SyntaxKind.ImportDeclaration + || node.kind === SyntaxKind.ExportAssignment + || node.kind === SyntaxKind.ExportDeclaration + || isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta" ? node - : undefined); + : undefined + } + + function walkTreeForExternalModuleIndicators(node: Node): Node { + return isAnExternalModuleIndicatorNode(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators); } const enum ParsingContext { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 31220c68d3c..57c69b77bb9 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -989,7 +989,7 @@ namespace ts { // moduleAugmentations has changed oldProgram.structureIsReused = StructureIsReused.SafeModules; } - if ((oldSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport) !== (newSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport)) { + if ((oldSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags) !== (newSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags)) { // dynamicImport has changed oldProgram.structureIsReused = StructureIsReused.SafeModules; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ac32d91c61a..42cf1325551 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -490,19 +490,21 @@ namespace ts { ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node - // This flag will be set when the parser encounters a dynamic import expression so that module resolution - // will not have to walk the tree if the flag is not set. However, this flag is just a approximation because - // once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport"). - // During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed - // during module resolution. However, the removal operation should not occur often and in the case of the + // These flags will be set when the parser encounters a dynamic import expression or 'import.meta' to avoid + // walking the tree if the flags are not set. However, these flags are just a approximation + // (hence why it's named "PossiblyContainsDynamicImport") because once set, the flags never get cleared. + // During editing, if a dynamic import is removed, incremental parsing will *NOT* clear this flag. + // This means that the tree will always be traversed during module resolution, or when looking for external module indicators. + // However, the removal operation should not occur often and in the case of the // removal, it is likely that users will add the import anyway. // The advantage of this approach is its simplicity. For the case of batch compilation, // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used. - /* @internal */ - PossiblyContainsDynamicImport = 1 << 19, - JSDoc = 1 << 20, // If node was parsed inside jsdoc - /* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. - /* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) + /* @internal */ PossiblyContainsDynamicImport = 1 << 19, + /* @internal */ PossiblyContainsImportMeta = 1 << 20, + + JSDoc = 1 << 21, // If node was parsed inside jsdoc + /* @internal */ Ambient = 1 << 22, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier. + /* @internal */ InWithStatement = 1 << 23, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) BlockScoped = Let | Const, @@ -514,6 +516,11 @@ namespace ts { // Exclude these flags when parsing a Type TypeExcludesFlags = YieldContext | AwaitContext, + + // Represents all flags that are potentially set once and + // never cleared on SourceFiles which get re-used in between incremental parses. + // See the comment above on `PossiblyContainsDynamicImport` and `PossiblyContainsImportMeta`. + /* @internal */ PermanentlySetIncrementalFlags = PossiblyContainsDynamicImport | PossiblyContainsImportMeta, } export const enum ModifierFlags { @@ -1754,7 +1761,7 @@ namespace ts { // for the same reasons we treat NewExpression as a PrimaryExpression. export interface MetaProperty extends PrimaryExpression { kind: SyntaxKind.MetaProperty; - keywordToken: SyntaxKind.NewKeyword; + keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; name: Identifier; } From f0081f0a049e2b4b3116eb9bdea84db1b19ccfc5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 10 Apr 2018 12:59:03 -0700 Subject: [PATCH 016/229] Basic checking for 'import.meta'. --- src/compiler/checker.ts | 35 +++++++++++++++++++++++++++++++---- src/lib/es5.d.ts | 4 ++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5634e06d5fd..444a23881c9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -434,6 +434,7 @@ namespace ts { let deferredGlobalAsyncIteratorType: GenericType; let deferredGlobalAsyncIterableIteratorType: GenericType; let deferredGlobalTemplateStringsArrayType: ObjectType; + let deferredGlobalImportMetaType: ObjectType; let deferredNodes: Node[]; const allPotentiallyUnusedIdentifiers = createMap>(); // key is file name @@ -7708,6 +7709,10 @@ namespace ts { return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType; } + function getGlobalImportMetaType() { + return deferredGlobalImportMetaType || (deferredGlobalImportMetaType = getGlobalType("ImportMeta" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType; + } + function getGlobalESSymbolConstructorSymbol(reportErrors: boolean) { return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol" as __String, reportErrors)); } @@ -18691,6 +18696,20 @@ namespace ts { function checkMetaProperty(node: MetaProperty) { checkGrammarMetaProperty(node); + + if (node.keywordToken === SyntaxKind.NewKeyword) { + return checkNewTargetMetaProperty(node); + } + + if (node.keywordToken === SyntaxKind.ImportKeyword) { + const file = getSourceFileOfNode(node); + Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); + Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module."); + return node.name.escapedText === "meta" ? getGlobalImportMetaType() : unknownType; + } + } + + function checkNewTargetMetaProperty(node: MetaProperty) { const container = getNewTargetContainer(node); if (!container) { error(node, Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target"); @@ -27554,10 +27573,18 @@ namespace ts { } function checkGrammarMetaProperty(node: MetaProperty) { - if (node.keywordToken === SyntaxKind.NewKeyword) { - if (node.name.escapedText !== "target") { - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "target"); - } + const escapedText = node.name.escapedText; + switch (node.keywordToken) { + case SyntaxKind.NewKeyword: + if (escapedText !== "target") { + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "target"); + } + break; + case SyntaxKind.ImportKeyword: + if (escapedText !== "meta") { + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "meta"); + } + break; } } diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index ea59c10c83e..cd4be60e8e4 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -505,6 +505,10 @@ interface TemplateStringsArray extends ReadonlyArray { readonly raw: ReadonlyArray; } +interface ImportMeta { + [propertyName: string]: any; +} + interface Math { /** The mathematical constant e. This is Euler's number, the base of natural logarithms. */ readonly E: number; From 910c5d338be381b34331d12120a11bea92ba7e65 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 10 Apr 2018 12:59:38 -0700 Subject: [PATCH 017/229] Accepted baselines. --- .../reference/api/tsserverlibrary.d.ts | 6 +- tests/baselines/reference/api/typescript.d.ts | 6 +- .../baselines/reference/importMeta.errors.txt | 107 +++--------------- tests/baselines/reference/importMeta.js | 17 ++- tests/baselines/reference/importMeta.symbols | 11 -- tests/baselines/reference/importMeta.types | 35 ++++-- 6 files changed, 50 insertions(+), 132 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a990c0af274..12231a0fa76 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -414,11 +414,11 @@ declare namespace ts { JavaScriptFile = 65536, ThisNodeOrAnySubNodesHasError = 131072, HasAggregatedChildData = 262144, - JSDoc = 1048576, + JSDoc = 2097152, BlockScoped = 3, ReachabilityCheckFlags = 384, ReachabilityAndEmitFlags = 1408, - ContextFlags = 6387712, + ContextFlags = 12679168, TypeExcludesFlags = 20480 } enum ModifierFlags { @@ -1070,7 +1070,7 @@ declare namespace ts { } interface MetaProperty extends PrimaryExpression { kind: SyntaxKind.MetaProperty; - keywordToken: SyntaxKind.NewKeyword; + keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; name: Identifier; } interface JsxElement extends PrimaryExpression { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 5b6ef18b680..3e20ece19b6 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -414,11 +414,11 @@ declare namespace ts { JavaScriptFile = 65536, ThisNodeOrAnySubNodesHasError = 131072, HasAggregatedChildData = 262144, - JSDoc = 1048576, + JSDoc = 2097152, BlockScoped = 3, ReachabilityCheckFlags = 384, ReachabilityAndEmitFlags = 1408, - ContextFlags = 6387712, + ContextFlags = 12679168, TypeExcludesFlags = 20480 } enum ModifierFlags { @@ -1070,7 +1070,7 @@ declare namespace ts { } interface MetaProperty extends PrimaryExpression { kind: SyntaxKind.MetaProperty; - keywordToken: SyntaxKind.NewKeyword; + keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; name: Identifier; } interface JsxElement extends PrimaryExpression { diff --git a/tests/baselines/reference/importMeta.errors.txt b/tests/baselines/reference/importMeta.errors.txt index 498da8efdc1..146b7afc211 100644 --- a/tests/baselines/reference/importMeta.errors.txt +++ b/tests/baselines/reference/importMeta.errors.txt @@ -1,70 +1,21 @@ error TS2468: Cannot find global value 'Promise'. tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. -tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1135: Argument expression expected. -tests/cases/conformance/es2019/importMeta/example.ts(3,65): error TS1135: Argument expression expected. -tests/cases/conformance/es2019/importMeta/example.ts(3,66): error TS2448: Block-scoped variable 'meta' used before its declaration. -tests/cases/conformance/es2019/importMeta/example.ts(6,9): error TS2451: Cannot redeclare block-scoped variable 'size'. -tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1109: Expression expected. -tests/cases/conformance/es2019/importMeta/example.ts(6,22): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/example.ts(6,27): error TS1005: ',' expected. -tests/cases/conformance/es2019/importMeta/example.ts(6,41): error TS1005: ',' expected. -tests/cases/conformance/es2019/importMeta/example.ts(6,49): error TS1005: ',' expected. -tests/cases/conformance/es2019/importMeta/example.ts(6,50): error TS2451: Cannot redeclare block-scoped variable 'size'. -tests/cases/conformance/es2019/importMeta/example.ts(6,55): error TS1005: ',' expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1109: Expression expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,22): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1109: Expression expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,22): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1109: Expression expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,22): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,29): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,30): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,36): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1109: Expression expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,21): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1109: Expression expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,21): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1109: Expression expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,21): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,28): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,29): error TS1134: Variable declaration expected. -tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,35): error TS1134: Variable declaration expected. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? !!! error TS2468: Cannot find global value 'Promise'. -==== tests/cases/conformance/es2019/importMeta/example.ts (12 errors) ==== +==== tests/cases/conformance/es2019/importMeta/example.ts (1 errors) ==== // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example (async () => { ~~~~~~~~~~~~~ !!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); - ~~~~~~ -!!! error TS1135: Argument expression expected. - ~ -!!! error TS1135: Argument expression expected. - ~~~~ -!!! error TS2448: Block-scoped variable 'meta' used before its declaration. const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; - ~~~~ -!!! error TS2451: Cannot redeclare block-scoped variable 'size'. - ~~~~~~ -!!! error TS1109: Expression expected. - ~ -!!! error TS1134: Variable declaration expected. - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS1005: ',' expected. - ~~~~ -!!! error TS2451: Cannot redeclare block-scoped variable 'size'. - ~~ -!!! error TS1005: ',' expected. const image = new Image(); image.src = URL.createObjectURL(blob); @@ -73,53 +24,21 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,35): error TS document.body.appendChild(image); })(); -==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (10 errors) ==== +==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (2 errors) ==== export let x = import.meta; - ~~~~~~ -!!! error TS1109: Expression expected. - ~ -!!! error TS1134: Variable declaration expected. export let y = import.metal; - ~~~~~~ -!!! error TS1109: Expression expected. - ~ -!!! error TS1134: Variable declaration expected. + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? export let z = import.import.import.malkovich; - ~~~~~~ -!!! error TS1109: Expression expected. - ~ -!!! error TS1134: Variable declaration expected. ~~~~~~ -!!! error TS1134: Variable declaration expected. - ~ -!!! error TS1134: Variable declaration expected. - ~~~~~~ -!!! error TS1134: Variable declaration expected. - ~ -!!! error TS1134: Variable declaration expected. +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? -==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (10 errors) ==== +==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (2 errors) ==== let globalA = import.meta; - ~~~~~~ -!!! error TS1109: Expression expected. - ~ -!!! error TS1134: Variable declaration expected. let globalB = import.metal; - ~~~~~~ -!!! error TS1109: Expression expected. - ~ -!!! error TS1134: Variable declaration expected. + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? let globalC = import.import.import.malkovich; - ~~~~~~ -!!! error TS1109: Expression expected. - ~ -!!! error TS1134: Variable declaration expected. ~~~~~~ -!!! error TS1134: Variable declaration expected. - ~ -!!! error TS1134: Variable declaration expected. - ~~~~~~ -!!! error TS1134: Variable declaration expected. - ~ -!!! error TS1134: Variable declaration expected. +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? \ No newline at end of file diff --git a/tests/baselines/reference/importMeta.js b/tests/baselines/reference/importMeta.js index 9391dbc4899..34148382d70 100644 --- a/tests/baselines/reference/importMeta.js +++ b/tests/baselines/reference/importMeta.js @@ -29,20 +29,19 @@ let globalC = import.import.import.malkovich; //// [example.js] // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example (async () => { - const response = await fetch(new URL("../hamsters.jpg", meta.url).toString()); + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); - const size = , meta, scriptElement, dataset, size; - || 300; + const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image); })(); //// [moduleLookingFile01.js] -export let x = , meta; -export let y = , metal; -export let z = , malkovich; +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; //// [scriptLookingFile01.js] -let globalA = , meta; -let globalB = , metal; -let globalC = , malkovich; +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; diff --git a/tests/baselines/reference/importMeta.symbols b/tests/baselines/reference/importMeta.symbols index cff36047d37..fa95f498554 100644 --- a/tests/baselines/reference/importMeta.symbols +++ b/tests/baselines/reference/importMeta.symbols @@ -6,7 +6,6 @@ >fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) >new URL("../hamsters.jpg", import.meta.url).toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --)) >URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) ->meta : Symbol(meta, Decl(example.ts, 5, 22)) >toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --)) const blob = await response.blob(); @@ -17,10 +16,6 @@ const size = import.meta.scriptElement.dataset.size || 300; >size : Symbol(size, Decl(example.ts, 5, 7)) ->meta : Symbol(meta, Decl(example.ts, 5, 22)) ->scriptElement : Symbol(scriptElement, Decl(example.ts, 5, 27)) ->dataset : Symbol(dataset, Decl(example.ts, 5, 41)) ->size : Symbol(size, Decl(example.ts, 5, 49)) const image = new Image(); >image : Symbol(image, Decl(example.ts, 7, 7)) @@ -57,26 +52,20 @@ === tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === export let x = import.meta; >x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10)) ->meta : Symbol(meta, Decl(moduleLookingFile01.ts, 0, 22)) export let y = import.metal; >y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10)) ->metal : Symbol(metal, Decl(moduleLookingFile01.ts, 1, 22)) export let z = import.import.import.malkovich; >z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10)) ->malkovich : Symbol(malkovich, Decl(moduleLookingFile01.ts, 2, 36)) === tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === let globalA = import.meta; >globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3)) ->meta : Symbol(meta, Decl(scriptLookingFile01.ts, 0, 21)) let globalB = import.metal; >globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3)) ->metal : Symbol(metal, Decl(scriptLookingFile01.ts, 1, 21)) let globalC = import.import.import.malkovich; >globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3)) ->malkovich : Symbol(malkovich, Decl(scriptLookingFile01.ts, 2, 35)) diff --git a/tests/baselines/reference/importMeta.types b/tests/baselines/reference/importMeta.types index 5004627cb4c..04384789f06 100644 --- a/tests/baselines/reference/importMeta.types +++ b/tests/baselines/reference/importMeta.types @@ -15,7 +15,8 @@ >new URL("../hamsters.jpg", import.meta.url) : URL >URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; } >"../hamsters.jpg" : "../hamsters.jpg" ->meta.url : any +>import.meta.url : any +>import.meta : ImportMeta >meta : any >url : any >toString : () => string @@ -30,13 +31,15 @@ const size = import.meta.scriptElement.dataset.size || 300; >size : any -> : any +>import.meta.scriptElement.dataset.size || 300 : any +>import.meta.scriptElement.dataset.size : any +>import.meta.scriptElement.dataset : any +>import.meta.scriptElement : any +>import.meta : ImportMeta >meta : any >scriptElement : any >dataset : any >size : any ->|| 300 : any -> : any >300 : 300 const image = new Image(); @@ -79,33 +82,41 @@ === tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === export let x = import.meta; ->x : any -> : any +>x : ImportMeta +>import.meta : ImportMeta >meta : any export let y = import.metal; >y : any -> : any +>import.metal : any >metal : any export let z = import.import.import.malkovich; >z : any -> : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any >malkovich : any === tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === let globalA = import.meta; ->globalA : any -> : any +>globalA : ImportMeta +>import.meta : ImportMeta >meta : any let globalB = import.metal; >globalB : any -> : any +>import.metal : any >metal : any let globalC = import.import.import.malkovich; >globalC : any -> : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any >malkovich : any From 7c0f249619877ea3f1619c686adf0348e4328654 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 10 Apr 2018 16:10:04 -0700 Subject: [PATCH 018/229] Added semicolon. --- src/compiler/parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e9a685d9d26..d61a57ce5ae 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6128,7 +6128,7 @@ namespace ts { || node.kind === SyntaxKind.ExportDeclaration || isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta" ? node - : undefined + : undefined; } function walkTreeForExternalModuleIndicators(node: Node): Node { From 56f4b2eea43537c8cde20db63b4b2b3592dac8af Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 10 Apr 2018 16:12:00 -0700 Subject: [PATCH 019/229] Provide an error when using 'import.meta' without setting 'esnext'. --- src/compiler/checker.ts | 15 +++++++++++---- src/compiler/diagnosticMessages.json | 4 ++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 444a23881c9..b2e4e3b9377 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18702,10 +18702,7 @@ namespace ts { } if (node.keywordToken === SyntaxKind.ImportKeyword) { - const file = getSourceFileOfNode(node); - Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); - Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module."); - return node.name.escapedText === "meta" ? getGlobalImportMetaType() : unknownType; + return checkImportMetaProperty(node); } } @@ -18725,6 +18722,16 @@ namespace ts { } } + function checkImportMetaProperty(node: MetaProperty) { + if (languageVersion < ScriptTarget.ESNext && modulekind < ModuleKind.ESNext) { + error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_options); + } + const file = getSourceFileOfNode(node); + Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); + Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module."); + return node.name.escapedText === "meta" ? getGlobalImportMetaType() : unknownType; + } + function getTypeOfParameter(symbol: Symbol) { const type = getTypeOfSymbol(symbol); if (strictNullChecks) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 69a90fbabf5..b91165ea17b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -967,6 +967,10 @@ "category": "Error", "code": 1342 }, + "The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.": { + "category": "Error", + "code": 1343 + }, "Duplicate identifier '{0}'.": { "category": "Error", From 4f497e6c0c250d68af4ae9045922eace82d3750f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 10 Apr 2018 16:28:50 -0700 Subject: [PATCH 020/229] Added tests around ES5, assigning to 'import.meta' and properties, global augmentations. --- .../es2019/importMeta/importMeta.ts | 13 ++++++ .../es2019/importMeta/importMetaES5.ts | 42 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/cases/conformance/es2019/importMeta/importMetaES5.ts diff --git a/tests/cases/conformance/es2019/importMeta/importMeta.ts b/tests/cases/conformance/es2019/importMeta/importMeta.ts index f23410fc536..c5022cf4abe 100644 --- a/tests/cases/conformance/es2019/importMeta/importMeta.ts +++ b/tests/cases/conformance/es2019/importMeta/importMeta.ts @@ -26,3 +26,16 @@ export let z = import.import.import.malkovich; let globalA = import.meta; let globalB = import.metal; let globalC = import.import.import.malkovich; + +// @Filename: assignmentTargets.ts +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; + +// @Filename augmentations.ts +declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } +} + +const { a, b, c } = import.meta.wellKnownProperty; \ No newline at end of file diff --git a/tests/cases/conformance/es2019/importMeta/importMetaES5.ts b/tests/cases/conformance/es2019/importMeta/importMetaES5.ts new file mode 100644 index 00000000000..b11a32ecc9b --- /dev/null +++ b/tests/cases/conformance/es2019/importMeta/importMetaES5.ts @@ -0,0 +1,42 @@ + +// @target: es5 +// @module: commonjs +// @lib: es5,dom + +// @Filename: example.ts +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); +})(); + +// @Filename: moduleLookingFile01.ts +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; + +// @Filename: scriptLookingFile01.ts +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; + +// @Filename: assignmentTargets.ts +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; + +// @Filename augmentations.ts +declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } +} + +const { a, b, c } = import.meta.wellKnownProperty; \ No newline at end of file From 1ea269af87787a2dbdde4e542936dc56905675bc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 10 Apr 2018 16:29:05 -0700 Subject: [PATCH 021/229] Accepted baselines. --- .../baselines/reference/importMeta.errors.txt | 17 +- tests/baselines/reference/importMeta.js | 16 ++ tests/baselines/reference/importMeta.symbols | 30 ++++ tests/baselines/reference/importMeta.types | 47 +++++ .../reference/importMetaES5.errors.txt | 98 ++++++++++ tests/baselines/reference/importMetaES5.js | 117 ++++++++++++ .../baselines/reference/importMetaES5.symbols | 101 +++++++++++ tests/baselines/reference/importMetaES5.types | 169 ++++++++++++++++++ 8 files changed, 594 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/importMetaES5.errors.txt create mode 100644 tests/baselines/reference/importMetaES5.js create mode 100644 tests/baselines/reference/importMetaES5.symbols create mode 100644 tests/baselines/reference/importMetaES5.types diff --git a/tests/baselines/reference/importMeta.errors.txt b/tests/baselines/reference/importMeta.errors.txt index 146b7afc211..2c44876fe23 100644 --- a/tests/baselines/reference/importMeta.errors.txt +++ b/tests/baselines/reference/importMeta.errors.txt @@ -1,4 +1,5 @@ error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? @@ -41,4 +42,18 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS let globalC = import.import.import.malkovich; ~~~~~~ !!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? - \ No newline at end of file + +==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (1 errors) ==== + export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; + import.meta = foo; + ~~~~~~~~~~~ +!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + + // @Filename augmentations.ts + declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } + } + + const { a, b, c } = import.meta.wellKnownProperty; \ No newline at end of file diff --git a/tests/baselines/reference/importMeta.js b/tests/baselines/reference/importMeta.js index 34148382d70..4b6fa5436f5 100644 --- a/tests/baselines/reference/importMeta.js +++ b/tests/baselines/reference/importMeta.js @@ -25,6 +25,18 @@ let globalA = import.meta; let globalB = import.metal; let globalC = import.import.import.malkovich; +//// [assignmentTargets.ts] +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; + +// @Filename augmentations.ts +declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } +} + +const { a, b, c } = import.meta.wellKnownProperty; //// [example.js] // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example @@ -45,3 +57,7 @@ export let z = import.import.import.malkovich; let globalA = import.meta; let globalB = import.metal; let globalC = import.import.import.malkovich; +//// [assignmentTargets.js] +export const foo = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; +const { a, b, c } = import.meta.wellKnownProperty; diff --git a/tests/baselines/reference/importMeta.symbols b/tests/baselines/reference/importMeta.symbols index fa95f498554..58d8f9807d4 100644 --- a/tests/baselines/reference/importMeta.symbols +++ b/tests/baselines/reference/importMeta.symbols @@ -69,3 +69,33 @@ let globalB = import.metal; let globalC = import.import.import.malkovich; >globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3)) +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + +import.meta = foo; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) + +// @Filename augmentations.ts +declare global { +>global : Symbol(global, Decl(assignmentTargets.ts, 1, 18)) + + interface ImportMeta { +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>a : Symbol(a, Decl(assignmentTargets.ts, 6, 24)) +>b : Symbol(b, Decl(assignmentTargets.ts, 6, 35)) +>c : Symbol(c, Decl(assignmentTargets.ts, 6, 46)) + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : Symbol(a, Decl(assignmentTargets.ts, 10, 7)) +>b : Symbol(b, Decl(assignmentTargets.ts, 10, 10)) +>c : Symbol(c, Decl(assignmentTargets.ts, 10, 13)) +>import.meta.wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) + diff --git a/tests/baselines/reference/importMeta.types b/tests/baselines/reference/importMeta.types index 04384789f06..c6140c8d05d 100644 --- a/tests/baselines/reference/importMeta.types +++ b/tests/baselines/reference/importMeta.types @@ -120,3 +120,50 @@ let globalC = import.import.import.malkovich; >import : any >malkovich : any +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : ImportMeta +>ImportMeta : ImportMeta +>import.meta.blah = import.meta.blue = import.meta : ImportMeta +>import.meta.blah : any +>import.meta : ImportMeta +>meta : any +>blah : any +>import.meta.blue = import.meta : ImportMeta +>import.meta.blue : any +>import.meta : ImportMeta +>meta : any +>blue : any +>import.meta : ImportMeta +>meta : any + +import.meta = foo; +>import.meta = foo : ImportMeta +>import.meta : ImportMeta +>meta : any +>foo : ImportMeta + +// @Filename augmentations.ts +declare global { +>global : any + + interface ImportMeta { +>ImportMeta : ImportMeta + + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : number +>b : string +>c : boolean +>import.meta.wellKnownProperty : { a: number; b: string; c: boolean; } +>import.meta : ImportMeta +>meta : any +>wellKnownProperty : { a: number; b: string; c: boolean; } + diff --git a/tests/baselines/reference/importMetaES5.errors.txt b/tests/baselines/reference/importMetaES5.errors.txt new file mode 100644 index 00000000000..46cc1107f69 --- /dev/null +++ b/tests/baselines/reference/importMetaES5.errors.txt @@ -0,0 +1,98 @@ +error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,32): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,51): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,70): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(11,21): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(1,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,15): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + + +!!! error TS2468: Cannot find global value 'Promise'. +==== tests/cases/conformance/es2019/importMeta/example.ts (3 errors) ==== + // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example + (async () => { + ~~~~~~~~~~~~~ +!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); + })(); + +==== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts (5 errors) ==== + export let x = import.meta; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + export let y = import.metal; + ~~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + export let z = import.import.import.malkovich; + ~~~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts (5 errors) ==== + let globalA = import.meta; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + let globalB = import.metal; + ~~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~~ +!!! error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + let globalC = import.import.import.malkovich; + ~~~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~~~ +!!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + +==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (6 errors) ==== + export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + import.meta = foo; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~~~~~~~~ +!!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. + + // @Filename augmentations.ts + declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } + } + + const { a, b, c } = import.meta.wellKnownProperty; + ~~~~~~~~~~~ +!!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. \ No newline at end of file diff --git a/tests/baselines/reference/importMetaES5.js b/tests/baselines/reference/importMetaES5.js new file mode 100644 index 00000000000..8ac695412ff --- /dev/null +++ b/tests/baselines/reference/importMetaES5.js @@ -0,0 +1,117 @@ +//// [tests/cases/conformance/es2019/importMeta/importMetaES5.ts] //// + +//// [example.ts] +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + const blob = await response.blob(); + + const size = import.meta.scriptElement.dataset.size || 300; + + const image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + + document.body.appendChild(image); +})(); + +//// [moduleLookingFile01.ts] +export let x = import.meta; +export let y = import.metal; +export let z = import.import.import.malkovich; + +//// [scriptLookingFile01.ts] +let globalA = import.meta; +let globalB = import.metal; +let globalC = import.import.import.malkovich; + +//// [assignmentTargets.ts] +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +import.meta = foo; + +// @Filename augmentations.ts +declare global { + interface ImportMeta { + wellKnownProperty: { a: number, b: string, c: boolean }; + } +} + +const { a, b, c } = import.meta.wellKnownProperty; + +//// [example.js] +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; +var _this = this; +Object.defineProperty(exports, "__esModule", { value: true }); +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(function () { return __awaiter(_this, void 0, void 0, function () { + var response, blob, size, image; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, fetch(new URL("../hamsters.jpg", import.meta.url).toString())]; + case 1: + response = _a.sent(); + return [4 /*yield*/, response.blob()]; + case 2: + blob = _a.sent(); + size = import.meta.scriptElement.dataset.size || 300; + image = new Image(); + image.src = URL.createObjectURL(blob); + image.width = image.height = size; + document.body.appendChild(image); + return [2 /*return*/]; + } + }); +}); })(); +//// [moduleLookingFile01.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.x = (import.meta); +exports.y = (import.metal); +exports.z = import.import.import.malkovich; +//// [scriptLookingFile01.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var globalA = import.meta; +var globalB = import.metal; +var globalC = import.import.import.malkovich; +//// [assignmentTargets.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.foo = import.meta.blah = import.meta.blue = import.meta; +import.meta = exports.foo; +var _a = import.meta.wellKnownProperty, a = _a.a, b = _a.b, c = _a.c; diff --git a/tests/baselines/reference/importMetaES5.symbols b/tests/baselines/reference/importMetaES5.symbols new file mode 100644 index 00000000000..58d8f9807d4 --- /dev/null +++ b/tests/baselines/reference/importMetaES5.symbols @@ -0,0 +1,101 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Symbol(response, Decl(example.ts, 2, 7)) +>fetch : Symbol(fetch, Decl(lib.dom.d.ts, --, --)) +>new URL("../hamsters.jpg", import.meta.url).toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>toString : Symbol(URL.toString, Decl(lib.dom.d.ts, --, --)) + + const blob = await response.blob(); +>blob : Symbol(blob, Decl(example.ts, 3, 7)) +>response.blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) +>response : Symbol(response, Decl(example.ts, 2, 7)) +>blob : Symbol(Body.blob, Decl(lib.dom.d.ts, --, --)) + + const size = import.meta.scriptElement.dataset.size || 300; +>size : Symbol(size, Decl(example.ts, 5, 7)) + + const image = new Image(); +>image : Symbol(image, Decl(example.ts, 7, 7)) +>Image : Symbol(Image, Decl(lib.dom.d.ts, --, --)) + + image.src = URL.createObjectURL(blob); +>image.src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>src : Symbol(HTMLImageElement.src, Decl(lib.dom.d.ts, --, --)) +>URL.createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>URL : Symbol(URL, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>createObjectURL : Symbol(createObjectURL, Decl(lib.dom.d.ts, --, --)) +>blob : Symbol(blob, Decl(example.ts, 3, 7)) + + image.width = image.height = size; +>image.width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>width : Symbol(HTMLImageElement.width, Decl(lib.dom.d.ts, --, --)) +>image.height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) +>height : Symbol(HTMLImageElement.height, Decl(lib.dom.d.ts, --, --)) +>size : Symbol(size, Decl(example.ts, 5, 7)) + + document.body.appendChild(image); +>document.body.appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>document.body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>document : Symbol(document, Decl(lib.dom.d.ts, --, --)) +>body : Symbol(Document.body, Decl(lib.dom.d.ts, --, --)) +>appendChild : Symbol(Node.appendChild, Decl(lib.dom.d.ts, --, --)) +>image : Symbol(image, Decl(example.ts, 7, 7)) + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : Symbol(x, Decl(moduleLookingFile01.ts, 0, 10)) + +export let y = import.metal; +>y : Symbol(y, Decl(moduleLookingFile01.ts, 1, 10)) + +export let z = import.import.import.malkovich; +>z : Symbol(z, Decl(moduleLookingFile01.ts, 2, 10)) + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : Symbol(globalA, Decl(scriptLookingFile01.ts, 0, 3)) + +let globalB = import.metal; +>globalB : Symbol(globalB, Decl(scriptLookingFile01.ts, 1, 3)) + +let globalC = import.import.import.malkovich; +>globalC : Symbol(globalC, Decl(scriptLookingFile01.ts, 2, 3)) + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + +import.meta = foo; +>foo : Symbol(foo, Decl(assignmentTargets.ts, 0, 12)) + +// @Filename augmentations.ts +declare global { +>global : Symbol(global, Decl(assignmentTargets.ts, 1, 18)) + + interface ImportMeta { +>ImportMeta : Symbol(ImportMeta, Decl(lib.es5.d.ts, --, --), Decl(assignmentTargets.ts, 4, 16)) + + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>a : Symbol(a, Decl(assignmentTargets.ts, 6, 24)) +>b : Symbol(b, Decl(assignmentTargets.ts, 6, 35)) +>c : Symbol(c, Decl(assignmentTargets.ts, 6, 46)) + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : Symbol(a, Decl(assignmentTargets.ts, 10, 7)) +>b : Symbol(b, Decl(assignmentTargets.ts, 10, 10)) +>c : Symbol(c, Decl(assignmentTargets.ts, 10, 13)) +>import.meta.wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) +>wellKnownProperty : Symbol(ImportMeta.wellKnownProperty, Decl(assignmentTargets.ts, 5, 24)) + diff --git a/tests/baselines/reference/importMetaES5.types b/tests/baselines/reference/importMetaES5.types new file mode 100644 index 00000000000..c6140c8d05d --- /dev/null +++ b/tests/baselines/reference/importMetaES5.types @@ -0,0 +1,169 @@ +=== tests/cases/conformance/es2019/importMeta/example.ts === +// Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example +(async () => { +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);})() : Promise +>(async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);}) : () => Promise +>async () => { const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; const image = new Image(); image.src = URL.createObjectURL(blob); image.width = image.height = size; document.body.appendChild(image);} : () => Promise + + const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); +>response : Response +>await fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Response +>fetch(new URL("../hamsters.jpg", import.meta.url).toString()) : Promise +>fetch : (input?: string | Request, init?: RequestInit) => Promise +>new URL("../hamsters.jpg", import.meta.url).toString() : string +>new URL("../hamsters.jpg", import.meta.url).toString : () => string +>new URL("../hamsters.jpg", import.meta.url) : URL +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; } +>"../hamsters.jpg" : "../hamsters.jpg" +>import.meta.url : any +>import.meta : ImportMeta +>meta : any +>url : any +>toString : () => string + + const blob = await response.blob(); +>blob : Blob +>await response.blob() : Blob +>response.blob() : Promise +>response.blob : () => Promise +>response : Response +>blob : () => Promise + + const size = import.meta.scriptElement.dataset.size || 300; +>size : any +>import.meta.scriptElement.dataset.size || 300 : any +>import.meta.scriptElement.dataset.size : any +>import.meta.scriptElement.dataset : any +>import.meta.scriptElement : any +>import.meta : ImportMeta +>meta : any +>scriptElement : any +>dataset : any +>size : any +>300 : 300 + + const image = new Image(); +>image : HTMLImageElement +>new Image() : HTMLImageElement +>Image : new (width?: number, height?: number) => HTMLImageElement + + image.src = URL.createObjectURL(blob); +>image.src = URL.createObjectURL(blob) : string +>image.src : string +>image : HTMLImageElement +>src : string +>URL.createObjectURL(blob) : string +>URL.createObjectURL : (object: any, options?: ObjectURLOptions) => string +>URL : { new (url: string, base?: string | URL): URL; prototype: URL; createObjectURL(object: any, options?: ObjectURLOptions): string; revokeObjectURL(url: string): void; } +>createObjectURL : (object: any, options?: ObjectURLOptions) => string +>blob : Blob + + image.width = image.height = size; +>image.width = image.height = size : any +>image.width : number +>image : HTMLImageElement +>width : number +>image.height = size : any +>image.height : number +>image : HTMLImageElement +>height : number +>size : any + + document.body.appendChild(image); +>document.body.appendChild(image) : HTMLImageElement +>document.body.appendChild : (newChild: T) => T +>document.body : HTMLElement +>document : Document +>body : HTMLElement +>appendChild : (newChild: T) => T +>image : HTMLImageElement + +})(); + +=== tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts === +export let x = import.meta; +>x : ImportMeta +>import.meta : ImportMeta +>meta : any + +export let y = import.metal; +>y : any +>import.metal : any +>metal : any + +export let z = import.import.import.malkovich; +>z : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts === +let globalA = import.meta; +>globalA : ImportMeta +>import.meta : ImportMeta +>meta : any + +let globalB = import.metal; +>globalB : any +>import.metal : any +>metal : any + +let globalC = import.import.import.malkovich; +>globalC : any +>import.import.import.malkovich : any +>import.import.import : any +>import.import : any +>import : any +>import : any +>malkovich : any + +=== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts === +export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; +>foo : ImportMeta +>ImportMeta : ImportMeta +>import.meta.blah = import.meta.blue = import.meta : ImportMeta +>import.meta.blah : any +>import.meta : ImportMeta +>meta : any +>blah : any +>import.meta.blue = import.meta : ImportMeta +>import.meta.blue : any +>import.meta : ImportMeta +>meta : any +>blue : any +>import.meta : ImportMeta +>meta : any + +import.meta = foo; +>import.meta = foo : ImportMeta +>import.meta : ImportMeta +>meta : any +>foo : ImportMeta + +// @Filename augmentations.ts +declare global { +>global : any + + interface ImportMeta { +>ImportMeta : ImportMeta + + wellKnownProperty: { a: number, b: string, c: boolean }; +>wellKnownProperty : { a: number; b: string; c: boolean; } +>a : number +>b : string +>c : boolean + } +} + +const { a, b, c } = import.meta.wellKnownProperty; +>a : number +>b : string +>c : boolean +>import.meta.wellKnownProperty : { a: number; b: string; c: boolean; } +>import.meta : ImportMeta +>meta : any +>wellKnownProperty : { a: number; b: string; c: boolean; } + From 0feefab765214f080e5d8db37bde42830a1c8884 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 10 Apr 2018 16:30:02 -0700 Subject: [PATCH 022/229] 'modulekind' -> 'moduleKind' --- src/compiler/checker.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b2e4e3b9377..aa9bbccffd9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -64,7 +64,7 @@ namespace ts { const compilerOptions = host.getCompilerOptions(); const languageVersion = getEmitScriptTarget(compilerOptions); - const modulekind = getEmitModuleKind(compilerOptions); + const moduleKind = getEmitModuleKind(compilerOptions); const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions); const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks"); const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes"); @@ -1085,7 +1085,7 @@ namespace ts { const declarationFile = getSourceFileOfNode(declaration); const useFile = getSourceFileOfNode(usage); if (declarationFile !== useFile) { - if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) || + if ((moduleKind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) || (!compilerOptions.outFile && !compilerOptions.out) || isInTypeQuery(usage) || declaration.flags & NodeFlags.Ambient) { @@ -18723,7 +18723,7 @@ namespace ts { } function checkImportMetaProperty(node: MetaProperty) { - if (languageVersion < ScriptTarget.ESNext && modulekind < ModuleKind.ESNext) { + if (languageVersion < ScriptTarget.ESNext && moduleKind < ModuleKind.ESNext) { error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_options); } const file = getSourceFileOfNode(node); @@ -22329,7 +22329,7 @@ namespace ts { function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier) { // No need to check for require or exports for ES6 modules and later - if (modulekind >= ModuleKind.ES2015 || compilerOptions.noEmit) { + if (moduleKind >= ModuleKind.ES2015 || compilerOptions.noEmit) { return; } @@ -24518,7 +24518,7 @@ namespace ts { } } else { - if (modulekind >= ModuleKind.ES2015 && !(node.flags & NodeFlags.Ambient)) { + if (moduleKind >= ModuleKind.ES2015 && !(node.flags & NodeFlags.Ambient)) { // Import equals declaration is deprecated in es6 or above grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); } @@ -24556,7 +24556,7 @@ namespace ts { error(node.moduleSpecifier, Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol)); } - if (modulekind !== ModuleKind.System && modulekind !== ModuleKind.ES2015 && modulekind !== ModuleKind.ESNext) { + if (moduleKind !== ModuleKind.System && moduleKind !== ModuleKind.ES2015 && moduleKind !== ModuleKind.ESNext) { checkExternalEmitHelpers(node, ExternalEmitHelpers.ExportStar); } } @@ -24629,11 +24629,11 @@ namespace ts { } if (node.isExportEquals && !(node.flags & NodeFlags.Ambient)) { - if (modulekind >= ModuleKind.ES2015) { + if (moduleKind >= ModuleKind.ES2015) { // export assignment is not supported in es6 modules grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead); } - else if (modulekind === ModuleKind.System) { + else if (moduleKind === ModuleKind.System) { // system modules does not support export assignment grammarErrorOnNode(node, Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system); } @@ -27790,7 +27790,7 @@ namespace ts { } function checkGrammarImportCallExpression(node: ImportCall): boolean { - if (modulekind === ModuleKind.ES2015) { + if (moduleKind === ModuleKind.ES2015) { return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules); } From b40592c34ebb27f95805c4e3c39e81323b9f5088 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Apr 2018 17:35:11 -1000 Subject: [PATCH 023/229] String index signatures do not apply to symbols --- src/compiler/checker.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e6ba58987fb..9abf5ec0277 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8151,8 +8151,9 @@ namespace ts { maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : - type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? keyofConstraintType : - keyofStringsOnly ? getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : + type.flags & TypeFlags.Any ? keyofConstraintType : + keyofStringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : + getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol); } From 0a37cd37362c10061ba9e7307eaf47a5f8821f6f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Apr 2018 17:35:27 -1000 Subject: [PATCH 024/229] Update test --- tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index 447fdebf68e..e0c1f544d97 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -190,13 +190,13 @@ function f51(k: K, s: string) { const x2 = k as string; } -function f52(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number) { +function f52(obj: { [x: string]: boolean }, k: Exclude, s: string, n: number) { const x1 = obj[s]; const x2 = obj[n]; const x3 = obj[k]; } -function f53(obj: { [x: string]: boolean }, k: K, s: string, n: number) { +function f53>(obj: { [x: string]: boolean }, k: K, s: string, n: number) { const x1 = obj[s]; const x2 = obj[n]; const x3 = obj[k]; From b746f8e8a4d4b20ba74efa17e45adcdf7e824823 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 10 Apr 2018 17:39:55 -1000 Subject: [PATCH 025/229] Accept new baselines --- .../reference/keyofAndIndexedAccess.js | 8 ++--- .../reference/keyofAndIndexedAccess.symbols | 36 ++++++++++--------- .../reference/keyofAndIndexedAccess.types | 22 ++++++------ 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 70f1c8b856e..422cef5a574 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -188,13 +188,13 @@ function f51(k: K, s: string) { const x2 = k as string; } -function f52(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number) { +function f52(obj: { [x: string]: boolean }, k: Exclude, s: string, n: number) { const x1 = obj[s]; const x2 = obj[n]; const x3 = obj[k]; } -function f53(obj: { [x: string]: boolean }, k: K, s: string, n: number) { +function f53>(obj: { [x: string]: boolean }, k: K, s: string, n: number) { const x1 = obj[s]; const x2 = obj[n]; const x3 = obj[k]; @@ -1048,8 +1048,8 @@ declare function f50(k: keyof T, s: string): void; declare function f51(k: K, s: string): void; declare function f52(obj: { [x: string]: boolean; -}, k: keyof T, s: string, n: number): void; -declare function f53(obj: { +}, k: Exclude, s: string, n: number): void; +declare function f53>(obj: { [x: string]: boolean; }, k: K, s: string, n: number): void; declare function f54(obj: T, key: keyof T): void; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index 1d59deb12b3..b1206a49388 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -651,25 +651,26 @@ function f51(k: K, s: string) { >k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 184, 35)) } -function f52(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number) { +function f52(obj: { [x: string]: boolean }, k: Exclude, s: string, n: number) { >f52 : Symbol(f52, Decl(keyofAndIndexedAccess.ts, 187, 1)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 189, 13)) >obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 189, 16)) >x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 189, 24)) >k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 189, 46)) +>Exclude : Symbol(Exclude, Decl(lib.d.ts, --, --)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 189, 13)) ->s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 189, 58)) ->n : Symbol(n, Decl(keyofAndIndexedAccess.ts, 189, 69)) +>s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 189, 75)) +>n : Symbol(n, Decl(keyofAndIndexedAccess.ts, 189, 86)) const x1 = obj[s]; >x1 : Symbol(x1, Decl(keyofAndIndexedAccess.ts, 190, 9)) >obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 189, 16)) ->s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 189, 58)) +>s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 189, 75)) const x2 = obj[n]; >x2 : Symbol(x2, Decl(keyofAndIndexedAccess.ts, 191, 9)) >obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 189, 16)) ->n : Symbol(n, Decl(keyofAndIndexedAccess.ts, 189, 69)) +>n : Symbol(n, Decl(keyofAndIndexedAccess.ts, 189, 86)) const x3 = obj[k]; >x3 : Symbol(x3, Decl(keyofAndIndexedAccess.ts, 192, 9)) @@ -677,32 +678,33 @@ function f52(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number) >k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 189, 46)) } -function f53(obj: { [x: string]: boolean }, k: K, s: string, n: number) { +function f53>(obj: { [x: string]: boolean }, k: K, s: string, n: number) { >f53 : Symbol(f53, Decl(keyofAndIndexedAccess.ts, 193, 1)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 195, 13)) >K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 195, 15)) +>Exclude : Symbol(Exclude, Decl(lib.d.ts, --, --)) >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 195, 13)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 195, 35)) ->x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 195, 43)) ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 195, 65)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 195, 52)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 195, 60)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 195, 82)) >K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 195, 15)) ->s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 195, 71)) ->n : Symbol(n, Decl(keyofAndIndexedAccess.ts, 195, 82)) +>s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 195, 88)) +>n : Symbol(n, Decl(keyofAndIndexedAccess.ts, 195, 99)) const x1 = obj[s]; >x1 : Symbol(x1, Decl(keyofAndIndexedAccess.ts, 196, 9)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 195, 35)) ->s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 195, 71)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 195, 52)) +>s : Symbol(s, Decl(keyofAndIndexedAccess.ts, 195, 88)) const x2 = obj[n]; >x2 : Symbol(x2, Decl(keyofAndIndexedAccess.ts, 197, 9)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 195, 35)) ->n : Symbol(n, Decl(keyofAndIndexedAccess.ts, 195, 82)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 195, 52)) +>n : Symbol(n, Decl(keyofAndIndexedAccess.ts, 195, 99)) const x3 = obj[k]; >x3 : Symbol(x3, Decl(keyofAndIndexedAccess.ts, 198, 9)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 195, 35)) ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 195, 65)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 195, 52)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 195, 82)) } function f54(obj: T, key: keyof T) { diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 462dde9ca03..4e41b58e664 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -92,7 +92,7 @@ type K11 = keyof Shape[]; // "length" | "toString" | ... >Shape : Shape type K12 = keyof Dictionary; // string ->K12 : string | number | symbol +>K12 : string | number >Dictionary : Dictionary >Shape : Shape @@ -136,7 +136,7 @@ type K20 = KeyOf; // "name" | "width" | "height" | "visible" >Shape : Shape type K21 = KeyOf>; // string ->K21 : string | number | symbol +>K21 : string | number >KeyOf : keyof T >Dictionary : Dictionary >Shape : Shape @@ -756,12 +756,13 @@ function f51(k: K, s: string) { >k : K } -function f52(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number) { ->f52 : (obj: { [x: string]: boolean; }, k: keyof T, s: string, n: number) => void +function f52(obj: { [x: string]: boolean }, k: Exclude, s: string, n: number) { +>f52 : (obj: { [x: string]: boolean; }, k: Exclude, s: string, n: number) => void >T : T >obj : { [x: string]: boolean; } >x : string ->k : keyof T +>k : Exclude +>Exclude : Exclude >T : T >s : string >n : number @@ -779,16 +780,17 @@ function f52(obj: { [x: string]: boolean }, k: keyof T, s: string, n: number) >n : number const x3 = obj[k]; ->x3 : { [x: string]: boolean; }[keyof T] ->obj[k] : { [x: string]: boolean; }[keyof T] +>x3 : { [x: string]: boolean; }[Exclude] +>obj[k] : { [x: string]: boolean; }[Exclude] >obj : { [x: string]: boolean; } ->k : keyof T +>k : Exclude } -function f53(obj: { [x: string]: boolean }, k: K, s: string, n: number) { ->f53 : (obj: { [x: string]: boolean; }, k: K, s: string, n: number) => void +function f53>(obj: { [x: string]: boolean }, k: K, s: string, n: number) { +>f53 : >(obj: { [x: string]: boolean; }, k: K, s: string, n: number) => void >T : T >K : K +>Exclude : Exclude >T : T >obj : { [x: string]: boolean; } >x : string From 4da2e5eda30eec7af1bf537c2f4b4f8352d5eb70 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Thu, 12 Apr 2018 19:31:07 +1000 Subject: [PATCH 026/229] fix: do not match MySymbol.import("mod") --- lib/typescriptServices.d.ts | 1 + src/compiler/scanner.ts | 3 +++ src/compiler/types.ts | 1 + src/harness/unittests/services/preProcessFile.ts | 13 +++++++++++++ src/services/preProcess.ts | 5 ++++- 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index ecf433425d9..c0d2a7db297 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -2929,6 +2929,7 @@ declare namespace ts { getTokenText(): string; getTokenValue(): string; hasExtendedUnicodeEscape(): boolean; + hasPrecedingDot(): boolean; hasPrecedingLineBreak(): boolean; isIdentifier(): boolean; isReservedWord(): boolean; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 43320b453c4..c1e7dbb299d 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -22,6 +22,7 @@ namespace ts { getTokenText(): string; getTokenValue(): string; hasExtendedUnicodeEscape(): boolean; + hasPrecedingDot(): boolean; hasPrecedingLineBreak(): boolean; isIdentifier(): boolean; isReservedWord(): boolean; @@ -833,6 +834,7 @@ namespace ts { getTokenText: () => text.substring(tokenPos, pos), getTokenValue: () => tokenValue, hasExtendedUnicodeEscape: () => (tokenFlags & TokenFlags.ExtendedUnicodeEscape) !== 0, + hasPrecedingDot: () => (tokenFlags & TokenFlags.PrecedingDot) !== 0, hasPrecedingLineBreak: () => (tokenFlags & TokenFlags.PrecedingLineBreak) !== 0, isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord, isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord, @@ -1469,6 +1471,7 @@ namespace ts { pos++; return token = SyntaxKind.MinusToken; case CharacterCodes.dot: + tokenFlags |= TokenFlags.PrecedingDot; if (isDigit(text.charCodeAt(pos + 1))) { tokenValue = scanNumber(); return token = SyntaxKind.NumericLiteral; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 987d403e7cd..a2eae1df6d5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1585,6 +1585,7 @@ namespace ts { BinarySpecifier = 1 << 7, // e.g. `0b0110010000000000` OctalSpecifier = 1 << 8, // e.g. `0o777` ContainsSeparator = 1 << 9, // e.g. `0b1100_0101` + PrecedingDot = 1 << 10, BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier, NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinarySpecifier | OctalSpecifier | ContainsSeparator } diff --git a/src/harness/unittests/services/preProcessFile.ts b/src/harness/unittests/services/preProcessFile.ts index 1e13bc3e345..f68af84f759 100644 --- a/src/harness/unittests/services/preProcessFile.ts +++ b/src/harness/unittests/services/preProcessFile.ts @@ -59,6 +59,19 @@ describe("PreProcessFile:", () => { }); }), + it("Do not return reference path of non-imports", () => { + test("Quill.import('delta');", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ false, + { + referencedFiles: [], + importedFiles: [], + typeReferenceDirectives: [], + ambientExternalModules: undefined, + isLibFile: false + }); + }), + it("Correctly return imported files", () => { test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", /*readImportFile*/ true, diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index fb138a87866..95bcbbe9bc6 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -78,7 +78,7 @@ namespace ts { */ function tryConsumeImport(): boolean { let token = scanner.getToken(); - if (token === SyntaxKind.ImportKeyword) { + if (token === SyntaxKind.ImportKeyword && !scanner.hasPrecedingDot()) { token = nextToken(); if (token === SyntaxKind.OpenParenToken) { token = nextToken(); @@ -293,6 +293,9 @@ namespace ts { // export import i = require("mod") // (for JavaScript files) require("mod") + // Do not look for: + // AnySymbol.import("mod") + while (true) { if (scanner.getToken() === SyntaxKind.EndOfFileToken) { break; From ee429ef2ea4ee83c7979857cc1ddb11e94fb3474 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Fri, 13 Apr 2018 11:39:29 +1000 Subject: [PATCH 027/229] use state --- lib/typescriptServices.d.ts | 1 - src/compiler/scanner.ts | 3 --- src/compiler/types.ts | 1 - src/services/preProcess.ts | 4 +++- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index c0d2a7db297..ecf433425d9 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -2929,7 +2929,6 @@ declare namespace ts { getTokenText(): string; getTokenValue(): string; hasExtendedUnicodeEscape(): boolean; - hasPrecedingDot(): boolean; hasPrecedingLineBreak(): boolean; isIdentifier(): boolean; isReservedWord(): boolean; diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index c1e7dbb299d..43320b453c4 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -22,7 +22,6 @@ namespace ts { getTokenText(): string; getTokenValue(): string; hasExtendedUnicodeEscape(): boolean; - hasPrecedingDot(): boolean; hasPrecedingLineBreak(): boolean; isIdentifier(): boolean; isReservedWord(): boolean; @@ -834,7 +833,6 @@ namespace ts { getTokenText: () => text.substring(tokenPos, pos), getTokenValue: () => tokenValue, hasExtendedUnicodeEscape: () => (tokenFlags & TokenFlags.ExtendedUnicodeEscape) !== 0, - hasPrecedingDot: () => (tokenFlags & TokenFlags.PrecedingDot) !== 0, hasPrecedingLineBreak: () => (tokenFlags & TokenFlags.PrecedingLineBreak) !== 0, isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord, isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord, @@ -1471,7 +1469,6 @@ namespace ts { pos++; return token = SyntaxKind.MinusToken; case CharacterCodes.dot: - tokenFlags |= TokenFlags.PrecedingDot; if (isDigit(text.charCodeAt(pos + 1))) { tokenValue = scanNumber(); return token = SyntaxKind.NumericLiteral; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a2eae1df6d5..987d403e7cd 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1585,7 +1585,6 @@ namespace ts { BinarySpecifier = 1 << 7, // e.g. `0b0110010000000000` OctalSpecifier = 1 << 8, // e.g. `0o777` ContainsSeparator = 1 << 9, // e.g. `0b1100_0101` - PrecedingDot = 1 << 10, BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier, NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinarySpecifier | OctalSpecifier | ContainsSeparator } diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 95bcbbe9bc6..3cf38eecd6e 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -13,6 +13,7 @@ namespace ts { const importedFiles: FileReference[] = []; let ambientExternalModules: { ref: FileReference, depth: number }[]; let braceNesting = 0; + let lastTokenWasDot = false; // assume that text represent an external module if it contains at least one top level import/export // ambient modules that are found inside external modules are interpreted as module augmentations let externalModule = false; @@ -25,6 +26,7 @@ namespace ts { else if (token === SyntaxKind.CloseBraceToken) { braceNesting--; } + lastTokenWasDot = token === SyntaxKind.DotToken; return token; } @@ -78,7 +80,7 @@ namespace ts { */ function tryConsumeImport(): boolean { let token = scanner.getToken(); - if (token === SyntaxKind.ImportKeyword && !scanner.hasPrecedingDot()) { + if (token === SyntaxKind.ImportKeyword && !lastTokenWasDot) { token = nextToken(); if (token === SyntaxKind.OpenParenToken) { token = nextToken(); From b0fb73c47cc7202f2477a4140dd3e2303d6aefce Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 3 Apr 2018 13:53:19 -0700 Subject: [PATCH 028/229] Typings cache is internal data structure --- src/server/editorServices.ts | 3 ++- src/server/typingsCache.ts | 3 ++- tests/baselines/reference/api/tsserverlibrary.d.ts | 12 ------------ 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 1f8f9d3b21b..dc2fa086a93 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -312,7 +312,8 @@ namespace ts.server { export class ProjectService { - public readonly typingsCache: TypingsCache; + /*@internal*/ + readonly typingsCache: TypingsCache; private readonly documentRegistry: DocumentRegistry; diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index f2642230f2d..6418b5f9cbe 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -24,7 +24,7 @@ namespace ts.server { globalTypingsCacheLocation: undefined }; - class TypingsCacheEntry { + interface TypingsCacheEntry { readonly typeAcquisition: TypeAcquisition; readonly compilerOptions: CompilerOptions; readonly typings: SortedReadonlyArray; @@ -80,6 +80,7 @@ namespace ts.server { return !arrayIsEqualTo(imports1, imports2); } + /*@internal*/ export class TypingsCache { private readonly perProjectCache: Map = createMap(); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 2e8e3f3871d..d102f467ade 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7602,17 +7602,6 @@ declare namespace ts.server { readonly globalTypingsCacheLocation: string; } const nullTypingsInstaller: ITypingsInstaller; - class TypingsCache { - private readonly installer; - private readonly perProjectCache; - constructor(installer: ITypingsInstaller); - isKnownTypesPackageName(name: string): boolean; - installPackage(options: InstallPackageOptionsWithProject): Promise; - getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray, forceRefresh: boolean): SortedReadonlyArray; - updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, newTypings: string[]): void; - deleteTypingsForProject(projectName: string): void; - onProjectClosed(project: Project): void; - } } declare namespace ts.server { enum ProjectKind { @@ -7960,7 +7949,6 @@ declare namespace ts.server { syntaxOnly?: boolean; } class ProjectService { - readonly typingsCache: TypingsCache; private readonly documentRegistry; /** * Container of all known scripts From c9479f7263fbd51f454da2b6363238200e0abca8 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 12 Apr 2018 14:55:22 -0700 Subject: [PATCH 029/229] Remove the specialized type UnresolvedImportsMap which is just a redirection and helps only in test only --- src/harness/unittests/typingsInstaller.ts | 6 +-- src/server/project.ts | 42 +++---------------- .../reference/api/tsserverlibrary.d.ts | 12 ------ 3 files changed, 9 insertions(+), 51 deletions(-) diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 1a19c98f477..5ec7a9d7a17 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -999,7 +999,7 @@ namespace ts.projectSystem { proj.updateGraph(); assert.deepEqual( - proj.getCachedUnresolvedImportsPerFile_TestOnly().get(f1.path), + proj.cachedUnresolvedImportsPerFile.get(f1.path), ["foo", "foo", "foo", "@bar/router", "@bar/common", "@bar/common"] ); @@ -1029,7 +1029,7 @@ namespace ts.projectSystem { const projectService = session.getProjectService(); checkNumberOfProjects(projectService, { inferredProjects: 1 }); const proj = projectService.inferredProjects[0]; - const version1 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion(); + const version1 = proj.lastCachedUnresolvedImportsList; // make a change that should not affect the structure of the program const changeRequest: server.protocol.ChangeRequest = { @@ -1047,7 +1047,7 @@ namespace ts.projectSystem { }; session.executeCommand(changeRequest); host.checkTimeoutQueueLengthAndRun(2); // This enqueues the updategraph and refresh inferred projects - const version2 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion(); + const version2 = proj.lastCachedUnresolvedImportsList; assert.notEqual(version1, version2, "set of unresolved imports should change"); }); diff --git a/src/server/project.ts b/src/server/project.ts index 1502d107dee..23583d9c71b 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -55,34 +55,6 @@ namespace ts.server { projectErrors: ReadonlyArray; } - export class UnresolvedImportsMap { - readonly perFileMap = createMap>(); - private version = 0; - - public clear() { - this.perFileMap.clear(); - this.version = 0; - } - - public getVersion() { - return this.version; - } - - public remove(path: Path) { - this.perFileMap.delete(path); - this.version++; - } - - public get(path: Path) { - return this.perFileMap.get(path); - } - - public set(path: Path, value: ReadonlyArray) { - this.perFileMap.set(path, value); - this.version++; - } - } - export interface PluginCreateInfo { project: Project; languageService: LanguageService; @@ -116,8 +88,10 @@ namespace ts.server { private missingFilesMap: Map; private plugins: PluginModule[] = []; - private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap(); - private lastCachedUnresolvedImportsList: SortedReadonlyArray; + /*@internal*/ + cachedUnresolvedImportsPerFile = createMap>(); + /*@internal*/ + lastCachedUnresolvedImportsList: SortedReadonlyArray; private lastFileExceededProgramSize: string | undefined; @@ -181,10 +155,6 @@ namespace ts.server { return hasOneOrMoreJsAndNoTsFiles(this); } - public getCachedUnresolvedImportsPerFile_TestOnly() { - return this.cachedUnresolvedImportsPerFile; - } - public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} { const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules"))); log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`); @@ -742,7 +712,7 @@ namespace ts.server { else { this.resolutionCache.invalidateResolutionOfFile(info.path); } - this.cachedUnresolvedImportsPerFile.remove(info.path); + this.cachedUnresolvedImportsPerFile.delete(info.path); if (detachFromProject) { info.detachFromProject(this); @@ -812,7 +782,7 @@ namespace ts.server { for (const file of changedFiles) { // delete cached information for changed files - this.cachedUnresolvedImportsPerFile.remove(file); + this.cachedUnresolvedImportsPerFile.delete(file); } // update builder only if language service is enabled diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index d102f467ade..29959a89d02 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7611,15 +7611,6 @@ declare namespace ts.server { } function allRootFilesAreJsOrDts(project: Project): boolean; function allFilesAreJsOrDts(project: Project): boolean; - class UnresolvedImportsMap { - readonly perFileMap: Map>; - private version; - clear(): void; - getVersion(): number; - remove(path: Path): void; - get(path: Path): ReadonlyArray; - set(path: Path, value: ReadonlyArray): void; - } interface PluginCreateInfo { project: Project; languageService: LanguageService; @@ -7652,8 +7643,6 @@ declare namespace ts.server { private externalFiles; private missingFilesMap; private plugins; - private cachedUnresolvedImportsPerFile; - private lastCachedUnresolvedImportsList; private lastFileExceededProgramSize; protected languageService: LanguageService; languageServiceEnabled: boolean; @@ -7688,7 +7677,6 @@ declare namespace ts.server { private readonly cancellationToken; isNonTsProject(): boolean; isJsOnlyProject(): boolean; - getCachedUnresolvedImportsPerFile_TestOnly(): UnresolvedImportsMap; static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {}; isKnownTypesPackageName(name: string): boolean; installPackage(options: InstallPackageOptions): Promise; From 35abe268242207c58558d3e7d6077ffe09e2f779 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 12 Apr 2018 15:21:20 -0700 Subject: [PATCH 030/229] Force new typings resolution only if there are more or less script infos in the project. This helps in reducing number of forced typing installation requests We anyways use changes in unresolved import array to determine if we need to enqueue new typing request Hence there is no need to soley rely on hasChanges from updateGraph which just indicates that we didnt reused the program (that does not mean new files were added to the program or changes in unresolved imports) --- src/compiler/core.ts | 7 ++++--- src/server/project.ts | 6 +++++- src/server/scriptInfo.ts | 8 +++++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index cdf68cb2dfa..b427c689c96 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2987,18 +2987,19 @@ namespace ts { } /** Remove the *first* occurrence of `item` from the array. */ - export function unorderedRemoveItem(array: T[], item: T): void { + export function unorderedRemoveItem(array: T[], item: T) { unorderedRemoveFirstItemWhere(array, element => element === item); } /** Remove the *first* element satisfying `predicate`. */ - function unorderedRemoveFirstItemWhere(array: T[], predicate: (element: T) => boolean): void { + function unorderedRemoveFirstItemWhere(array: T[], predicate: (element: T) => boolean) { for (let i = 0; i < array.length; i++) { if (predicate(array[i])) { unorderedRemoveItemAt(array, i); - break; + return true; } } + return false; } export type GetCanonicalFileName = (fileName: string) => string; diff --git a/src/server/project.ts b/src/server/project.ts index 23583d9c71b..47bfb03a189 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -92,6 +92,8 @@ namespace ts.server { cachedUnresolvedImportsPerFile = createMap>(); /*@internal*/ lastCachedUnresolvedImportsList: SortedReadonlyArray; + /*@internal*/ + hasMoreOrLessScriptInfos = false; private lastFileExceededProgramSize: string | undefined; @@ -777,6 +779,8 @@ namespace ts.server { this.resolutionCache.startRecordingFilesWithChangedResolutions(); let hasChanges = this.updateGraphWorker(); + const hasMoreOrLessScriptInfos = this.hasMoreOrLessScriptInfos; + this.hasMoreOrLessScriptInfos = false; const changedFiles: ReadonlyArray = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || emptyArray; @@ -803,7 +807,7 @@ namespace ts.server { this.lastCachedUnresolvedImportsList = toDeduplicatedSortedArray(result); } - const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasChanges); + const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasMoreOrLessScriptInfos); if (!arrayIsEqualTo(this.typingFiles, cachedTypings)) { this.typingFiles = cachedTypings; this.markAsDirty(); diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index db56973d796..074fde298aa 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -304,6 +304,7 @@ namespace ts.server { const isNew = !this.isAttached(project); if (isNew) { this.containingProjects.push(project); + project.hasMoreOrLessScriptInfos = true; if (!project.getCompilerOptions().preserveSymlinks) { this.ensureRealPath(); } @@ -328,19 +329,24 @@ namespace ts.server { return; case 1: if (this.containingProjects[0] === project) { + project.hasMoreOrLessScriptInfos = true; this.containingProjects.pop(); } break; case 2: if (this.containingProjects[0] === project) { + project.hasMoreOrLessScriptInfos = true; this.containingProjects[0] = this.containingProjects.pop(); } else if (this.containingProjects[1] === project) { + project.hasMoreOrLessScriptInfos = true; this.containingProjects.pop(); } break; default: - unorderedRemoveItem(this.containingProjects, project); + if (unorderedRemoveItem(this.containingProjects, project)) { + project.hasMoreOrLessScriptInfos = true; + } break; } } From 60b19f5782b87af71a2ca567da9c3f9d50638df2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 12 Apr 2018 16:47:40 -0700 Subject: [PATCH 031/229] Invalidate the unresolved import resolutions when typing files are set This has 3 changes: 1. In updateGraph when enqueue the typing installation request (depending on unresolved imports) 2. When ActionSet event is received, invalidate only files with unresolved imports and resolve those. 3. When ActionInvalidate event is received, typing installer has detected some change in global typing cache location, so just enqueue a new typing installation request. This will repeat the cycle of setting correct typings and pickiing unresolved imports --- src/compiler/resolutionCache.ts | 20 ++++- .../unittests/tsserverProjectSystem.ts | 1 - src/harness/unittests/typingsInstaller.ts | 75 ++++++++++++++++++- src/server/editorServices.ts | 10 +-- src/server/project.ts | 71 ++++++++++++------ src/server/typingsCache.ts | 16 ++-- .../reference/api/tsserverlibrary.d.ts | 5 +- 7 files changed, 153 insertions(+), 45 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index c2b96649cf2..2cd39068de1 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -10,6 +10,7 @@ namespace ts { invalidateResolutionOfFile(filePath: Path): void; removeResolutionsOfFile(filePath: Path): void; + setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map): void; createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution; startCachingPerDirectoryResolution(): void; @@ -74,6 +75,7 @@ namespace ts { export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string, logChangesWhenResolvingModule: boolean): ResolutionCache { let filesWithChangedSetOfUnresolvedImports: Path[] | undefined; let filesWithInvalidatedResolutions: Map | undefined; + let filesWithInvalidatedNonRelativeUnresolvedImports: Map | undefined; let allFilesHaveInvalidatedResolution = false; const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory()); @@ -122,6 +124,7 @@ namespace ts { resolveTypeReferenceDirectives, removeResolutionsOfFile, invalidateResolutionOfFile, + setFilesWithInvalidatedNonRelativeUnresolvedImports, createHasInvalidatedResolution, updateTypeRootsWatch, closeTypeRootsWatch, @@ -173,7 +176,8 @@ namespace ts { } const collected = filesWithInvalidatedResolutions; filesWithInvalidatedResolutions = undefined; - return path => collected && collected.has(path); + return path => (collected && collected.has(path)) || + (filesWithInvalidatedNonRelativeUnresolvedImports && filesWithInvalidatedNonRelativeUnresolvedImports.has(path)); } function clearPerDirectoryResolutions() { @@ -184,6 +188,7 @@ namespace ts { function finishCachingPerDirectoryResolution() { allFilesHaveInvalidatedResolution = false; + filesWithInvalidatedNonRelativeUnresolvedImports = undefined; directoryWatchesOfFailedLookups.forEach((watcher, path) => { if (watcher.refCount === 0) { directoryWatchesOfFailedLookups.delete(path); @@ -237,13 +242,15 @@ namespace ts { const resolvedModules: R[] = []; const compilerOptions = resolutionHost.getCompilationSettings(); - + const hasInvalidatedNonRelativeUnresolvedImport = logChanges && filesWithInvalidatedNonRelativeUnresolvedImports && filesWithInvalidatedNonRelativeUnresolvedImports.has(path); const seenNamesInFile = createMap(); for (const name of names) { let resolution = resolutionsInFile.get(name); // Resolution is valid if it is present and not invalidated if (!seenNamesInFile.has(name) && - allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated) { + allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated || + // If the name is unresolved import that was invalidated, recalculate + (hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && !getResolutionWithResolvedFileName(resolution))) { const existingResolution = resolution; const resolutionInDirectory = perDirectoryResolution.get(name); if (resolutionInDirectory) { @@ -284,7 +291,7 @@ namespace ts { if (oldResolution === newResolution) { return true; } - if (!oldResolution || !newResolution || oldResolution.isInvalidated) { + if (!oldResolution || !newResolution) { return false; } const oldResult = getResolutionWithResolvedFileName(oldResolution); @@ -577,6 +584,11 @@ namespace ts { ); } + function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: Map) { + Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined); + filesWithInvalidatedNonRelativeUnresolvedImports = filesMap; + } + function invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath: Path, isCreatingWatchedDirectory: boolean) { let isChangedFailedLookupLocation: (location: string) => boolean; if (isCreatingWatchedDirectory) { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index b167ed21b94..10912b4fb87 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -7294,7 +7294,6 @@ namespace ts.projectSystem { const host = createServerHost(files); const session = createSession(host); const projectService = session.getProjectService(); - debugger; session.executeCommandSeq({ command: protocol.CommandTypes.Open, arguments: { diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 5ec7a9d7a17..b6d5a20ef9a 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -1006,7 +1006,7 @@ namespace ts.projectSystem { installer.installAll(/*expectedCount*/ 1); }); - it("should recompute resolutions after typings are installed", () => { + it("cached unresolved typings are not recomputed if program structure did not change", () => { const host = createServerHost([]); const session = createSession(host); const f = { @@ -1048,7 +1048,7 @@ namespace ts.projectSystem { session.executeCommand(changeRequest); host.checkTimeoutQueueLengthAndRun(2); // This enqueues the updategraph and refresh inferred projects const version2 = proj.lastCachedUnresolvedImportsList; - assert.notEqual(version1, version2, "set of unresolved imports should change"); + assert.strictEqual(version1, version2, "set of unresolved imports should change"); }); it("expired cache entry (inferred project, should install typings)", () => { @@ -1621,4 +1621,75 @@ namespace ts.projectSystem { assert.deepEqual(commands, expectedCommands, "commands"); }); }); + + describe("recomputing resolutions of unresolved imports", () => { + const globalTypingsCacheLocation = "/tmp"; + const appPath = "/a/b/app.js" as Path; + const foooPath = "/a/b/node_modules/fooo/index.d.ts"; + function verifyResolvedModuleOfFooo(project: server.Project) { + const foooResolution = project.getLanguageService().getProgram().getSourceFileByPath(appPath).resolvedModules.get("fooo"); + assert.equal(foooResolution.resolvedFileName, foooPath); + return foooResolution; + } + + function verifyUnresolvedImportResolutions(appContents: string, typingNames: string[], typingFiles: FileOrFolder[]) { + const app: FileOrFolder = { + path: appPath, + content: `${appContents}import * as x from "fooo";` + }; + const fooo: FileOrFolder = { + path: foooPath, + content: `export var x: string;` + }; + const host = createServerHost([app, fooo]); + const installer = new (class extends Installer { + constructor() { + super(host, { globalTypingsCacheLocation, typesRegistry: createTypesRegistry("foo") }); + } + installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) { + executeCommand(this, host, typingNames, typingFiles, cb); + } + })(); + const projectService = createProjectService(host, { typingsInstaller: installer }); + projectService.openClientFile(app.path); + projectService.checkNumberOfProjects({ inferredProjects: 1 }); + + const proj = projectService.inferredProjects[0]; + checkProjectActualFiles(proj, [app.path, fooo.path]); + const foooResolution1 = verifyResolvedModuleOfFooo(proj); + + installer.installAll(/*expectedCount*/ 1); + host.checkTimeoutQueueLengthAndRun(2); + checkProjectActualFiles(proj, typingFiles.map(f => f.path).concat(app.path, fooo.path)); + const foooResolution2 = verifyResolvedModuleOfFooo(proj); + assert.strictEqual(foooResolution1, foooResolution2); + } + + it("correctly invalidate the resolutions with typing names", () => { + verifyUnresolvedImportResolutions('import * as a from "foo";', ["foo"], [{ + path: `${globalTypingsCacheLocation}/node_modules/foo/index.d.ts`, + content: "export function a(): void;" + }]); + }); + + it("correctly invalidate the resolutions with typing names that are trimmed", () => { + const fooAA: FileOrFolder = { + path: `${globalTypingsCacheLocation}/node_modules/foo/a/a.d.ts`, + content: "export function a (): void;" + }; + const fooAB: FileOrFolder = { + path: `${globalTypingsCacheLocation}/node_modules/foo/a/b.d.ts`, + content: "export function b (): void;" + }; + const fooAC: FileOrFolder = { + path: `${globalTypingsCacheLocation}/node_modules/foo/a/c.d.ts`, + content: "export function c (): void;" + }; + verifyUnresolvedImportResolutions(` + import * as a from "foo/a/a"; + import * as b from "foo/a/b"; + import * as c from "foo/a/c"; + `, ["foo"], [fooAA, fooAB, fooAC]); + }); + }); } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index dc2fa086a93..1271b98c1c7 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -524,13 +524,13 @@ namespace ts.server { } switch (response.kind) { case ActionSet: - project.resolutionCache.clear(); - this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typeAcquisition, response.unresolvedImports, response.typings); + // Update the typing files and update the project + project.updateTypingFiles(this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typeAcquisition, response.unresolvedImports, response.typings)); break; case ActionInvalidate: - project.resolutionCache.clear(); - this.typingsCache.deleteTypingsForProject(response.projectName); - break; + // Do not clear resolution cache, there was changes detected in typings, so enque typing request and let it get us correct results + this.typingsCache.enqueueInstallTypingsForProject(project, project.lastCachedUnresolvedImportsList, /*forceRefresh*/ true); + return; } this.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project); } diff --git a/src/server/project.ts b/src/server/project.ts index 47bfb03a189..67469cc69d8 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -89,7 +89,18 @@ namespace ts.server { private plugins: PluginModule[] = []; /*@internal*/ + /** + * This is map from files to unresolved imports in it + * Maop does not contain entries for files that do not have unresolved imports + * This helps in containing the set of files to invalidate + */ cachedUnresolvedImportsPerFile = createMap>(); + + /** + * This is the set that has entry to true if file doesnt contain any unresolved import + */ + private filesWithNoUnresolvedImports = createMap(); + /*@internal*/ lastCachedUnresolvedImportsList: SortedReadonlyArray; /*@internal*/ @@ -143,7 +154,8 @@ namespace ts.server { /*@internal*/ hasChangedAutomaticTypeDirectiveNames = false; - private typingFiles: SortedReadonlyArray; + /*@internal*/ + typingFiles: SortedReadonlyArray = emptyArray; private readonly cancellationToken: ThrottledCancellationToken; @@ -554,6 +566,7 @@ namespace ts.server { this.resolutionCache.clear(); this.resolutionCache = undefined; this.cachedUnresolvedImportsPerFile = undefined; + this.filesWithNoUnresolvedImports = undefined; this.directoryStructureHost = undefined; // Clean up file watchers waiting for missing files @@ -714,6 +727,7 @@ namespace ts.server { else { this.resolutionCache.invalidateResolutionOfFile(info.path); } + this.filesWithNoUnresolvedImports.delete(info.path); this.cachedUnresolvedImportsPerFile.delete(info.path); if (detachFromProject) { @@ -735,16 +749,21 @@ namespace ts.server { } /* @internal */ - private extractUnresolvedImportsFromSourceFile(file: SourceFile, result: Push, ambientModules: string[]) { + private extractUnresolvedImportsFromSourceFile(file: SourceFile, result: string[] | undefined, ambientModules: string[]): string[] | undefined { + // No unresolve imports in this file + if (this.filesWithNoUnresolvedImports.has(file.path)) { + return result; + } + const cached = this.cachedUnresolvedImportsPerFile.get(file.path); if (cached) { // found cached result - use it and return for (const f of cached) { - result.push(f); + (result || (result = [])).push(f); } - return; + return result; } - let unresolvedImports: string[]; + let unresolvedImports: string[] | undefined; if (file.resolvedModules) { file.resolvedModules.forEach((resolvedModule, name) => { // pick unresolved non-relative names @@ -760,11 +779,17 @@ namespace ts.server { trimmed = trimmed.substr(0, i); } (unresolvedImports || (unresolvedImports = [])).push(trimmed); - result.push(trimmed); + (result || (result = [])).push(trimmed); } }); } - this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray); + if (unresolvedImports) { + this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports); + } + else { + this.filesWithNoUnresolvedImports.set(file.path, true); + } + return result; function isAmbientlyDeclaredModule(name: string) { return ambientModules.some(m => m === name); @@ -778,7 +803,7 @@ namespace ts.server { updateGraph(): boolean { this.resolutionCache.startRecordingFilesWithChangedResolutions(); - let hasChanges = this.updateGraphWorker(); + const hasChanges = this.updateGraphWorker(); const hasMoreOrLessScriptInfos = this.hasMoreOrLessScriptInfos; this.hasMoreOrLessScriptInfos = false; @@ -787,6 +812,7 @@ namespace ts.server { for (const file of changedFiles) { // delete cached information for changed files this.cachedUnresolvedImportsPerFile.delete(file); + this.filesWithNoUnresolvedImports.delete(file); } // update builder only if language service is enabled @@ -799,20 +825,15 @@ namespace ts.server { // (can reuse cached imports for files that were not changed) // 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch if (hasChanges || changedFiles.length) { - const result: string[] = []; + let result: string[] | undefined; const ambientModules = this.program.getTypeChecker().getAmbientModules().map(mod => stripQuotes(mod.getName())); for (const sourceFile of this.program.getSourceFiles()) { - this.extractUnresolvedImportsFromSourceFile(sourceFile, result, ambientModules); + result = this.extractUnresolvedImportsFromSourceFile(sourceFile, result, ambientModules); } - this.lastCachedUnresolvedImportsList = toDeduplicatedSortedArray(result); + this.lastCachedUnresolvedImportsList = result ? toDeduplicatedSortedArray(result) : emptyArray; } - const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasMoreOrLessScriptInfos); - if (!arrayIsEqualTo(this.typingFiles, cachedTypings)) { - this.typingFiles = cachedTypings; - this.markAsDirty(); - hasChanges = this.updateGraphWorker() || hasChanges; - } + this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasMoreOrLessScriptInfos); } else { this.lastCachedUnresolvedImportsList = undefined; @@ -824,6 +845,13 @@ namespace ts.server { return !hasChanges; } + /*@internal*/ + updateTypingFiles(typingFiles: SortedReadonlyArray) { + this.typingFiles = typingFiles; + // Invalidate files with unresolved imports + this.resolutionCache.setFilesWithInvalidatedNonRelativeUnresolvedImports(this.cachedUnresolvedImportsPerFile); + } + /* @internal */ getCurrentProgram() { return this.program; @@ -959,15 +987,14 @@ namespace ts.server { setCompilerOptions(compilerOptions: CompilerOptions) { if (compilerOptions) { compilerOptions.allowNonTsExtensions = true; - if (changesAffectModuleResolution(this.compilerOptions, compilerOptions)) { - // reset cached unresolved imports if changes in compiler options affected module resolution - this.cachedUnresolvedImportsPerFile.clear(); - this.lastCachedUnresolvedImportsList = undefined; - } const oldOptions = this.compilerOptions; this.compilerOptions = compilerOptions; this.setInternalCompilerOptionsForEmittingJsFiles(); if (changesAffectModuleResolution(oldOptions, compilerOptions)) { + // reset cached unresolved imports if changes in compiler options affected module resolution + this.cachedUnresolvedImportsPerFile.clear(); + this.filesWithNoUnresolvedImports.clear(); + this.lastCachedUnresolvedImportsList = undefined; this.resolutionCache.clear(); } this.markAsDirty(); diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts index 6418b5f9cbe..c255757481f 100644 --- a/src/server/typingsCache.ts +++ b/src/server/typingsCache.ts @@ -95,15 +95,14 @@ namespace ts.server { return this.installer.installPackage(options); } - getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray, forceRefresh: boolean): SortedReadonlyArray { + enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray, forceRefresh: boolean) { const typeAcquisition = project.getTypeAcquisition(); if (!typeAcquisition || !typeAcquisition.enable) { - return emptyArray; + return; } const entry = this.perProjectCache.get(project.getProjectName()); - const result: SortedReadonlyArray = entry ? entry.typings : emptyArray; if (forceRefresh || !entry || typeAcquisitionChanged(typeAcquisition, entry.typeAcquisition) || @@ -114,28 +113,25 @@ namespace ts.server { this.perProjectCache.set(project.getProjectName(), { compilerOptions: project.getCompilationSettings(), typeAcquisition, - typings: result, + typings: entry ? entry.typings : emptyArray, unresolvedImports, poisoned: true }); // something has been changed, issue a request to update typings this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports); } - return result; } updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, newTypings: string[]) { + const typings = toSortedArray(newTypings); this.perProjectCache.set(projectName, { compilerOptions, typeAcquisition, - typings: toSortedArray(newTypings), + typings, unresolvedImports, poisoned: false }); - } - - deleteTypingsForProject(projectName: string) { - this.perProjectCache.delete(projectName); + return !typeAcquisition || !typeAcquisition.enable ? emptyArray : typings; } onProjectClosed(project: Project) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 29959a89d02..53c23b1d382 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7643,6 +7643,10 @@ declare namespace ts.server { private externalFiles; private missingFilesMap; private plugins; + /** + * This is the set that has entry to true if file doesnt contain any unresolved import + */ + private filesWithNoUnresolvedImports; private lastFileExceededProgramSize; protected languageService: LanguageService; languageServiceEnabled: boolean; @@ -7673,7 +7677,6 @@ declare namespace ts.server { * This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project */ private projectStateVersion; - private typingFiles; private readonly cancellationToken; isNonTsProject(): boolean; isJsOnlyProject(): boolean; From 82e9a7595b9c289875e15c706f608e913fce2fcb Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 13 Apr 2018 15:15:09 -0700 Subject: [PATCH 032/229] Invoked should be property on watchers map instead of local variable since watchers arent closed if they need to be reopened --- src/server/typingsInstaller/typingsInstaller.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 8d482241d1b..f79564f6f98 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -64,11 +64,13 @@ namespace ts.server.typingsInstaller { onRequestCompleted: RequestCompletedAction; } + type ProjectWatchers = Map & { isInvoked?: boolean; }; + export abstract class TypingsInstaller { private readonly packageNameToTypingLocation: Map = createMap(); private readonly missingTypingsSet: Map = createMap(); private readonly knownCachesSet: Map = createMap(); - private readonly projectWatchers = createMap>(); + private readonly projectWatchers = createMap(); private safeList: JsTyping.SafeList | undefined; readonly pendingRunRequests: PendingRequest[] = []; @@ -378,8 +380,8 @@ namespace ts.server.typingsInstaller { this.projectWatchers.set(projectName, watchers); } + watchers.isInvoked = false; // handler should be invoked once for the entire set of files since it will trigger full rediscovery of typings - let isInvoked = false; const isLoggingEnabled = this.log.isEnabled(); mutateMap( watchers, @@ -392,11 +394,11 @@ namespace ts.server.typingsInstaller { } const watcher = this.installTypingHost.watchFile(file, (f, eventKind) => { if (isLoggingEnabled) { - this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${isInvoked}'`); + this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${watchers.isInvoked}'`); } - if (!isInvoked) { + if (!watchers.isInvoked) { + watchers.isInvoked = true; this.sendResponse({ projectName, kind: ActionInvalidate }); - isInvoked = true; } }, /*pollingInterval*/ 2000); return isLoggingEnabled ? { From bd3e854b31781edfd03f087faf6de21b2bf1b783 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 20:51:09 -0700 Subject: [PATCH 033/229] Automatically configure tsc output and provide a new 'diagnosticStyle' option. --- src/compiler/commandLineParser.ts | 8 ++++++++ src/compiler/sys.ts | 4 ++++ src/compiler/tsc.ts | 11 +++++++++-- src/compiler/types.ts | 6 ++++-- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 470bd111492..252ea9e8df0 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -56,6 +56,14 @@ namespace ts { category: Diagnostics.Command_line_Options, description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, + { + name: "diagnosticStyle", + type: createMapFromTemplate({ + auto: DiagnosticStyle.Auto, + pretty: DiagnosticStyle.Pretty, + simple: DiagnosticStyle.Simple, + }), + }, { name: "preserveWatchOutput", type: "boolean", diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index c37315a2e56..2a4616732dd 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -428,6 +428,7 @@ namespace ts { newLine: string; useCaseSensitiveFileNames: boolean; write(s: string): void; + writeOutputIsTty?(): boolean; readFile(path: string, encoding?: string): string | undefined; getFileSize?(path: string): number; writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; @@ -561,6 +562,9 @@ namespace ts { write(s: string): void { process.stdout.write(s); }, + writeOutputIsTty() { + return process.stdout.isTTY; + }, readFile, writeFile, watchFile: getWatchFile(), diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index f16ca98c93d..5012b73e98a 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -19,11 +19,18 @@ namespace ts { let reportDiagnostic = createDiagnosticReporter(sys); function updateReportDiagnostic(options: CompilerOptions) { - if (options.pretty) { + if (shouldBePretty(options)) { reportDiagnostic = createDiagnosticReporter(sys, /*pretty*/ true); } } + function shouldBePretty(options: CompilerOptions) { + if ((typeof options.pretty === "undefined" && typeof options.diagnosticStyle === "undefined") || options.diagnosticStyle === DiagnosticStyle.Auto) { + return !!sys.writeOutputIsTty && sys.writeOutputIsTty(); + } + return options.diagnosticStyle === DiagnosticStyle.Pretty || options.pretty; + } + function padLeft(s: string, length: number) { while (s.length < length) { s = " " + s; @@ -159,7 +166,7 @@ namespace ts { } function createWatchStatusReporter(options: CompilerOptions) { - return ts.createWatchStatusReporter(sys, !!options.pretty); + return ts.createWatchStatusReporter(sys, shouldBePretty(options)); } function createWatchOfConfigFile(configParseResult: ParsedCommandLine, optionsToExtend: CompilerOptions) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 987d403e7cd..802c175b573 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4193,7 +4193,8 @@ namespace ts { preserveSymlinks?: boolean; /* @internal */ preserveWatchOutput?: boolean; project?: string; - /* @internal */ pretty?: DiagnosticStyle; + /* @internal */ pretty?: boolean; + /* @internal */ diagnosticStyle?: DiagnosticStyle; reactNamespace?: string; jsxFactory?: string; removeComments?: boolean; @@ -4293,8 +4294,9 @@ namespace ts { /* @internal */ export const enum DiagnosticStyle { - Simple, + Auto, Pretty, + Simple, } /** Either a parsed command line or a parsed tsconfig.json */ From 7fd1dda13cf520a48671f553ba36a4e3e4f55350 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 20:59:06 -0700 Subject: [PATCH 034/229] Accepted baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 2e8e3f3871d..dfe2f613078 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2888,6 +2888,7 @@ declare namespace ts { newLine: string; useCaseSensitiveFileNames: boolean; write(s: string): void; + writeOutputIsTty?(): boolean; readFile(path: string, encoding?: string): string | undefined; getFileSize?(path: string): number; writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 378949d5b5b..6963bd95f72 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2888,6 +2888,7 @@ declare namespace ts { newLine: string; useCaseSensitiveFileNames: boolean; write(s: string): void; + writeOutputIsTty?(): boolean; readFile(path: string, encoding?: string): string | undefined; getFileSize?(path: string): number; writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; From b409888cbcce4b0c393d9fa7b255905b5a6efcad Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:01:24 -0700 Subject: [PATCH 035/229] Added tests. --- .../taggedTemplatesWithTypeArguments1.ts | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts diff --git a/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts new file mode 100644 index 00000000000..90509938dbc --- /dev/null +++ b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts @@ -0,0 +1,44 @@ +// @target: esnext + +declare function f(strs: TemplateStringsArray, ...callbacks: Array<(x: T) => any>): void; + +interface Stuff { + x: number; + y: string; + z: boolean; +} + +export const a = f ` + hello + ${stuff => stuff.x} + brave + ${stuff => stuff.y} + world + ${stuff => stuff.z} +`; + +declare function g( + strs: TemplateStringsArray, + t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V): T | U | V; + +export const b = g ` + hello + ${stuff => stuff.x} + brave + ${stuff => stuff.y} + world + ${stuff => stuff.z} +`; + +declare let obj: { + prop: (strs: TemplateStringsArray, x: (input: T) => T) => { + returnedObjProp: { + lastOne: T + } + } +} + +export const c = obj["prop"] `${(input) => { ...input }}` +c.returnedProp.x; +c.returnedProp.y; +c.returnedProp.z; \ No newline at end of file From 23567ee05daa02b3acf1ad3e19431c8415701908 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:01:34 -0700 Subject: [PATCH 036/229] Accepted baselines. --- ...ggedTemplatesWithTypeArguments1.errors.txt | 82 ++++++++ .../taggedTemplatesWithTypeArguments1.js | 66 +++++++ .../taggedTemplatesWithTypeArguments1.symbols | 136 +++++++++++++ .../taggedTemplatesWithTypeArguments1.types | 181 ++++++++++++++++++ 4 files changed, 465 insertions(+) create mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments1.js create mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols create mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments1.types diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt new file mode 100644 index 00000000000..700c98d54fe --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt @@ -0,0 +1,82 @@ +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(9,18): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(9,20): error TS2693: 'Stuff' only refers to a type, but is being used as a value here. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(22,20): error TS2693: 'Stuff' only refers to a type, but is being used as a value here. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(22,50): error TS1005: ',' expected. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(39,18): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(39,30): error TS2693: 'Stuff' only refers to a type, but is being used as a value here. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(39,53): error TS1128: Declaration or statement expected. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(40,3): error TS2339: Property 'returnedProp' does not exist on type 'boolean'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(41,3): error TS2339: Property 'returnedProp' does not exist on type 'boolean'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(42,3): error TS2339: Property 'returnedProp' does not exist on type 'boolean'. + + +==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts (10 errors) ==== + declare function f(strs: TemplateStringsArray, ...callbacks: Array<(x: T) => any>): void; + + interface Stuff { + x: number; + y: string; + z: boolean; + } + + export const a = f ` + ~~~~~~~~~~ + ~~~~~ +!!! error TS2693: 'Stuff' only refers to a type, but is being used as a value here. + hello + ~~~~~~~~~ + ${stuff => stuff.x} + ~~~~~~~~~~~~~~~~~~~~~~~ + brave + ~~~~~~~~~ + ${stuff => stuff.y} + ~~~~~~~~~~~~~~~~~~~~~~~ + world + ~~~~~~~~~ + ${stuff => stuff.z} + ~~~~~~~~~~~~~~~~~~~~~~~ + `; + ~ +!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string'. + + declare function g( + strs: TemplateStringsArray, + t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V): T | U | V; + + export const b = g ` + ~~~~~ +!!! error TS2693: 'Stuff' only refers to a type, but is being used as a value here. + ~ +!!! error TS1005: ',' expected. + hello + ${stuff => stuff.x} + brave + ${stuff => stuff.y} + world + ${stuff => stuff.z} + `; + + declare let obj: { + prop: (strs: TemplateStringsArray, x: (input: T) => T) => { + returnedObjProp: { + lastOne: T + } + } + } + + export const c = obj["prop"] `${(input) => { ...input }}` + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string'. + ~~~~~ +!!! error TS2693: 'Stuff' only refers to a type, but is being used as a value here. + ~~~ +!!! error TS1128: Declaration or statement expected. + c.returnedProp.x; + ~~~~~~~~~~~~ +!!! error TS2339: Property 'returnedProp' does not exist on type 'boolean'. + c.returnedProp.y; + ~~~~~~~~~~~~ +!!! error TS2339: Property 'returnedProp' does not exist on type 'boolean'. + c.returnedProp.z; + ~~~~~~~~~~~~ +!!! error TS2339: Property 'returnedProp' does not exist on type 'boolean'. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js new file mode 100644 index 00000000000..629571b4db0 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js @@ -0,0 +1,66 @@ +//// [taggedTemplatesWithTypeArguments1.ts] +declare function f(strs: TemplateStringsArray, ...callbacks: Array<(x: T) => any>): void; + +interface Stuff { + x: number; + y: string; + z: boolean; +} + +export const a = f ` + hello + ${stuff => stuff.x} + brave + ${stuff => stuff.y} + world + ${stuff => stuff.z} +`; + +declare function g( + strs: TemplateStringsArray, + t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V): T | U | V; + +export const b = g ` + hello + ${stuff => stuff.x} + brave + ${stuff => stuff.y} + world + ${stuff => stuff.z} +`; + +declare let obj: { + prop: (strs: TemplateStringsArray, x: (input: T) => T) => { + returnedObjProp: { + lastOne: T + } + } +} + +export const c = obj["prop"] `${(input) => { ...input }}` +c.returnedProp.x; +c.returnedProp.y; +c.returnedProp.z; + +//// [taggedTemplatesWithTypeArguments1.js] +export const a = f < Stuff > ` + hello + ${stuff => stuff.x} + brave + ${stuff => stuff.y} + world + ${stuff => stuff.z} +`; +export const b = g < Stuff, number, string, boolean; + > ` + hello + ${stuff => stuff.x} + brave + ${stuff => stuff.y} + world + ${stuff => stuff.z} +`; +export const c = obj["prop"] < Stuff > `${(input) => { input; }}`; +c.returnedProp.x; +c.returnedProp.y; +c.returnedProp.z; diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols new file mode 100644 index 00000000000..85170aad228 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols @@ -0,0 +1,136 @@ +=== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts === +declare function f(strs: TemplateStringsArray, ...callbacks: Array<(x: T) => any>): void; +>f : Symbol(f, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 0)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 19)) +>strs : Symbol(strs, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 22)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.es5.d.ts, --, --)) +>callbacks : Symbol(callbacks, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 49)) +>Array : Symbol(Array, Decl(lib.es2016.array.include.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --) ... and 1 more) +>x : Symbol(x, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 71)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 19)) + +interface Stuff { +>Stuff : Symbol(Stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 92)) + + x: number; +>x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) + + y: string; +>y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) + + z: boolean; +>z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) +} + +export const a = f ` +>a : Symbol(a, Decl(taggedTemplatesWithTypeArguments1.ts, 8, 12)) +>f : Symbol(f, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 0)) + + hello + ${stuff => stuff.x} +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 10, 6)) +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 10, 6)) + + brave + ${stuff => stuff.y} +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 12, 6)) +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 12, 6)) + + world + ${stuff => stuff.z} +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 14, 6)) +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 14, 6)) + +`; + +declare function g( +>g : Symbol(g, Decl(taggedTemplatesWithTypeArguments1.ts, 15, 2)) +>Input : Symbol(Input, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 19)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 25)) +>U : Symbol(U, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 28)) +>V : Symbol(V, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 31)) + + strs: TemplateStringsArray, +>strs : Symbol(strs, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 35)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.es5.d.ts, --, --)) + + t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V): T | U | V; +>t : Symbol(t, Decl(taggedTemplatesWithTypeArguments1.ts, 18, 31)) +>i : Symbol(i, Decl(taggedTemplatesWithTypeArguments1.ts, 19, 8)) +>Input : Symbol(Input, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 19)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 25)) +>u : Symbol(u, Decl(taggedTemplatesWithTypeArguments1.ts, 19, 23)) +>i : Symbol(i, Decl(taggedTemplatesWithTypeArguments1.ts, 19, 28)) +>Input : Symbol(Input, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 19)) +>U : Symbol(U, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 28)) +>v : Symbol(v, Decl(taggedTemplatesWithTypeArguments1.ts, 19, 43)) +>i : Symbol(i, Decl(taggedTemplatesWithTypeArguments1.ts, 19, 48)) +>Input : Symbol(Input, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 19)) +>V : Symbol(V, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 31)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 25)) +>U : Symbol(U, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 28)) +>V : Symbol(V, Decl(taggedTemplatesWithTypeArguments1.ts, 17, 31)) + +export const b = g ` +>b : Symbol(b, Decl(taggedTemplatesWithTypeArguments1.ts, 21, 12)) +>g : Symbol(g, Decl(taggedTemplatesWithTypeArguments1.ts, 15, 2)) +>number : Symbol(number, Decl(taggedTemplatesWithTypeArguments1.ts, 21, 25)) +>string : Symbol(string, Decl(taggedTemplatesWithTypeArguments1.ts, 21, 33)) +>boolean : Symbol(boolean, Decl(taggedTemplatesWithTypeArguments1.ts, 21, 41)) + + hello + ${stuff => stuff.x} +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 23, 6)) +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 23, 6)) + + brave + ${stuff => stuff.y} +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 25, 6)) +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 25, 6)) + + world + ${stuff => stuff.z} +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 27, 6)) +>stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 27, 6)) + +`; + +declare let obj: { +>obj : Symbol(obj, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 11)) + + prop: (strs: TemplateStringsArray, x: (input: T) => T) => { +>prop : Symbol(prop, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 18)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 11)) +>strs : Symbol(strs, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 14)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 41)) +>input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 46)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 11)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 11)) + + returnedObjProp: { +>returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) + + lastOne: T +>lastOne : Symbol(lastOne, Decl(taggedTemplatesWithTypeArguments1.ts, 32, 26)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 11)) + } + } +} + +export const c = obj["prop"] `${(input) => { ...input }}` +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 12)) +>obj : Symbol(obj, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 11)) +>"prop" : Symbol(prop, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 18)) +>input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 40)) +>input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 40)) + +c.returnedProp.x; +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 12)) + +c.returnedProp.y; +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 12)) + +c.returnedProp.z; +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 12)) + diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types new file mode 100644 index 00000000000..9999bb67bd8 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types @@ -0,0 +1,181 @@ +=== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts === +declare function f(strs: TemplateStringsArray, ...callbacks: Array<(x: T) => any>): void; +>f : (strs: TemplateStringsArray, ...callbacks: ((x: T) => any)[]) => void +>T : T +>strs : TemplateStringsArray +>TemplateStringsArray : TemplateStringsArray +>callbacks : ((x: T) => any)[] +>Array : T[] +>x : T +>T : T + +interface Stuff { +>Stuff : Stuff + + x: number; +>x : number + + y: string; +>y : string + + z: boolean; +>z : boolean +} + +export const a = f ` +>a : boolean +>f ` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : boolean +>ff : (strs: TemplateStringsArray, ...callbacks: ((x: T) => any)[]) => void +>Stuff : any +>` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : string + + hello + ${stuff => stuff.x} +>stuff => stuff.x : (stuff: any) => any +>stuff : any +>stuff.x : any +>stuff : any +>x : any + + brave + ${stuff => stuff.y} +>stuff => stuff.y : (stuff: any) => any +>stuff : any +>stuff.y : any +>stuff : any +>y : any + + world + ${stuff => stuff.z} +>stuff => stuff.z : (stuff: any) => any +>stuff : any +>stuff.z : any +>stuff : any +>z : any + +`; + +declare function g( +>g : (strs: TemplateStringsArray, t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V) => T | U | V +>Input : Input +>T : T +>U : U +>V : V + + strs: TemplateStringsArray, +>strs : TemplateStringsArray +>TemplateStringsArray : TemplateStringsArray + + t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V): T | U | V; +>t : (i: Input) => T +>i : Input +>Input : Input +>T : T +>u : (i: Input) => U +>i : Input +>Input : Input +>U : U +>v : (i: Input) => V +>i : Input +>Input : Input +>V : V +>T : T +>U : U +>V : V + +export const b = g ` +>b : boolean +>gg : (strs: TemplateStringsArray, t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V) => T | U | V +>Stuff : any +>number : any +>string : any +>boolean : any +>> ` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : boolean +> : any +>` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : string + + hello + ${stuff => stuff.x} +>stuff => stuff.x : (stuff: any) => any +>stuff : any +>stuff.x : any +>stuff : any +>x : any + + brave + ${stuff => stuff.y} +>stuff => stuff.y : (stuff: any) => any +>stuff : any +>stuff.y : any +>stuff : any +>y : any + + world + ${stuff => stuff.z} +>stuff => stuff.z : (stuff: any) => any +>stuff : any +>stuff.z : any +>stuff : any +>z : any + +`; + +declare let obj: { +>obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: { lastOne: T; }; }; } + + prop: (strs: TemplateStringsArray, x: (input: T) => T) => { +>prop : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: { lastOne: T; }; } +>T : T +>strs : TemplateStringsArray +>TemplateStringsArray : TemplateStringsArray +>x : (input: T) => T +>input : T +>T : T +>T : T + + returnedObjProp: { +>returnedObjProp : { lastOne: T; } + + lastOne: T +>lastOne : T +>T : T + } + } +} + +export const c = obj["prop"] `${(input) => { ...input }}` +>c : boolean +>obj["prop"] `${(input) => { ...input }}` : boolean +>obj["prop"]obj["prop"] : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: { lastOne: T; }; } +>obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: { lastOne: T; }; }; } +>"prop" : "prop" +>Stuff : any +>`${(input) => { ...input }}` : string +>(input) => { ...input } : (input: any) => void +>input : any +>input : any + +c.returnedProp.x; +>c.returnedProp.x : any +>c.returnedProp : any +>c : boolean +>returnedProp : any +>x : any + +c.returnedProp.y; +>c.returnedProp.y : any +>c.returnedProp : any +>c : boolean +>returnedProp : any +>y : any + +c.returnedProp.z; +>c.returnedProp.z : any +>c.returnedProp : any +>c : boolean +>returnedProp : any +>z : any + From 60b6d3fbce4f25d099995e2a62a9252f8546d5bf Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:14:13 -0700 Subject: [PATCH 037/229] Fixed up test. Thanks arrow functions... --- .../taggedTemplatesWithTypeArguments1.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts index 90509938dbc..2f3fc71e65d 100644 --- a/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts +++ b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts @@ -32,13 +32,16 @@ export const b = g ` declare let obj: { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { - returnedObjProp: { - lastOne: T - } + returnedObjProp: T } } -export const c = obj["prop"] `${(input) => { ...input }}` -c.returnedProp.x; -c.returnedProp.y; -c.returnedProp.z; \ No newline at end of file +export let c = obj["prop"] `${(input) => ({ ...input })}` +c.returnedObjProp.x; +c.returnedObjProp.y; +c.returnedObjProp.z; + +c = obj.prop `${(input) => ({ ...input })}` +c.returnedObjProp.x; +c.returnedObjProp.y; +c.returnedObjProp.z; \ No newline at end of file From da7967a3cf535c131791e94f52bc0eb6d872fae3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:15:02 -0700 Subject: [PATCH 038/229] Added basic support for parsing/emitting type arguments in tagged template expressions. --- src/compiler/emitter.ts | 1 + src/compiler/parser.ts | 36 +++++++++++++++++++++++++++--------- src/compiler/types.ts | 1 + 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 289f332cd33..2b01f2fdda1 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1462,6 +1462,7 @@ namespace ts { function emitTaggedTemplateExpression(node: TaggedTemplateExpression) { emitExpression(node.tag); + emitTypeArguments(node, node.typeArguments); writeSpace(); emitExpression(node.template); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 74d54ed28fb..29d57c846f5 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -223,6 +223,7 @@ namespace ts { visitNodes(cbNode, cbNodes, (node).arguments); case SyntaxKind.TaggedTemplateExpression: return visitNode(cbNode, (node).tag) || + visitNodes(cbNode, cbNodes, (node).typeArguments) || visitNode(cbNode, (node).template); case SyntaxKind.TypeAssertionExpression: return visitNode(cbNode, (node).type) || @@ -4362,18 +4363,28 @@ namespace ts { continue; } - if (token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead) { - const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, expression.pos); - tagExpression.tag = expression; - tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral - ? parseLiteralNode() - : parseTemplateExpression(); - expression = finishNode(tagExpression); + if (isTemplateStartOfTaggedTemplate()) { + expression = parseTaggedTemplateRest(expression, /*typeArguments*/ undefined); continue; } return expression; } + + } + + function isTemplateStartOfTaggedTemplate() { + return token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead; + } + + function parseTaggedTemplateRest(tag: LeftHandSideExpression, typeArguments: NodeArray | undefined) { + const tagExpression = createNode(SyntaxKind.TaggedTemplateExpression, tag.pos); + tagExpression.tag = tag; + tagExpression.typeArguments = typeArguments; + tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral + ? parseLiteralNode() + : parseTemplateExpression(); + return finishNode(tagExpression); } function parseCallExpressionRest(expression: LeftHandSideExpression): LeftHandSideExpression { @@ -4389,6 +4400,11 @@ namespace ts { return expression; } + if (isTemplateStartOfTaggedTemplate()) { + expression = parseTaggedTemplateRest(expression, typeArguments); + continue; + } + const callExpr = createNode(SyntaxKind.CallExpression, expression.pos); callExpr.expression = expression; callExpr.typeArguments = typeArguments; @@ -4436,8 +4452,10 @@ namespace ts { function canFollowTypeArgumentsInExpression(): boolean { switch (token()) { case SyntaxKind.OpenParenToken: // foo( - // this case are the only case where this token can legally follow a type argument - // list. So we definitely want to treat this as a type arg list. + case SyntaxKind.NoSubstitutionTemplateLiteral: // foo `...` + case SyntaxKind.TemplateHead: // foo `...${100}...` + // these are the only tokens can legally follow a type argument + // list. So we definitely want to treat them as type arg lists. case SyntaxKind.DotToken: // foo. case SyntaxKind.CloseParenToken: // foo) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 987d403e7cd..f96ea05cb12 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1726,6 +1726,7 @@ namespace ts { export interface TaggedTemplateExpression extends MemberExpression { kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; + typeArguments?: NodeArray; template: TemplateLiteral; } From 090f6bd77c53f2fe945dfefba69a1f7a99fe6ab8 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:23:05 -0700 Subject: [PATCH 039/229] Accepted baselines. --- .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + ...ggedTemplatesWithTypeArguments1.errors.txt | 92 ++++++----- .../taggedTemplatesWithTypeArguments1.js | 34 ++-- .../taggedTemplatesWithTypeArguments1.symbols | 62 +++++-- .../taggedTemplatesWithTypeArguments1.types | 155 ++++++++++-------- 6 files changed, 204 insertions(+), 141 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 2e8e3f3871d..ae99f93ae1a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1050,6 +1050,7 @@ declare namespace ts { interface TaggedTemplateExpression extends MemberExpression { kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; + typeArguments?: NodeArray; template: TemplateLiteral; } type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 378949d5b5b..c419eceaf95 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1050,6 +1050,7 @@ declare namespace ts { interface TaggedTemplateExpression extends MemberExpression { kind: SyntaxKind.TaggedTemplateExpression; tag: LeftHandSideExpression; + typeArguments?: NodeArray; template: TemplateLiteral; } type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement; diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt index 700c98d54fe..6b732dbf4aa 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt @@ -1,16 +1,18 @@ -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(9,18): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(9,20): error TS2693: 'Stuff' only refers to a type, but is being used as a value here. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(22,20): error TS2693: 'Stuff' only refers to a type, but is being used as a value here. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(22,50): error TS1005: ',' expected. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(39,18): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(39,30): error TS2693: 'Stuff' only refers to a type, but is being used as a value here. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(39,53): error TS1128: Declaration or statement expected. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(40,3): error TS2339: Property 'returnedProp' does not exist on type 'boolean'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(41,3): error TS2339: Property 'returnedProp' does not exist on type 'boolean'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(42,3): error TS2339: Property 'returnedProp' does not exist on type 'boolean'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(11,22): error TS2339: Property 'x' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(13,22): error TS2339: Property 'y' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(15,22): error TS2339: Property 'z' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(24,22): error TS2339: Property 'x' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(26,22): error TS2339: Property 'y' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(28,22): error TS2339: Property 'z' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(38,19): error TS2339: Property 'x' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(39,19): error TS2339: Property 'y' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(40,19): error TS2339: Property 'z' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(43,19): error TS2339: Property 'x' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(44,19): error TS2339: Property 'y' does not exist on type '{}'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(45,19): error TS2339: Property 'z' does not exist on type '{}'. -==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts (10 errors) ==== +==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts (12 errors) ==== declare function f(strs: TemplateStringsArray, ...callbacks: Array<(x: T) => any>): void; interface Stuff { @@ -20,63 +22,63 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(42,3) } export const a = f ` - ~~~~~~~~~~ - ~~~~~ -!!! error TS2693: 'Stuff' only refers to a type, but is being used as a value here. hello - ~~~~~~~~~ ${stuff => stuff.x} - ~~~~~~~~~~~~~~~~~~~~~~~ + ~ +!!! error TS2339: Property 'x' does not exist on type '{}'. brave - ~~~~~~~~~ ${stuff => stuff.y} - ~~~~~~~~~~~~~~~~~~~~~~~ + ~ +!!! error TS2339: Property 'y' does not exist on type '{}'. world - ~~~~~~~~~ ${stuff => stuff.z} - ~~~~~~~~~~~~~~~~~~~~~~~ + ~ +!!! error TS2339: Property 'z' does not exist on type '{}'. `; - ~ -!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string'. declare function g( strs: TemplateStringsArray, t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V): T | U | V; export const b = g ` - ~~~~~ -!!! error TS2693: 'Stuff' only refers to a type, but is being used as a value here. - ~ -!!! error TS1005: ',' expected. hello ${stuff => stuff.x} + ~ +!!! error TS2339: Property 'x' does not exist on type '{}'. brave ${stuff => stuff.y} + ~ +!!! error TS2339: Property 'y' does not exist on type '{}'. world ${stuff => stuff.z} + ~ +!!! error TS2339: Property 'z' does not exist on type '{}'. `; declare let obj: { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { - returnedObjProp: { - lastOne: T - } + returnedObjProp: T } } - export const c = obj["prop"] `${(input) => { ...input }}` - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string'. - ~~~~~ -!!! error TS2693: 'Stuff' only refers to a type, but is being used as a value here. - ~~~ -!!! error TS1128: Declaration or statement expected. - c.returnedProp.x; - ~~~~~~~~~~~~ -!!! error TS2339: Property 'returnedProp' does not exist on type 'boolean'. - c.returnedProp.y; - ~~~~~~~~~~~~ -!!! error TS2339: Property 'returnedProp' does not exist on type 'boolean'. - c.returnedProp.z; - ~~~~~~~~~~~~ -!!! error TS2339: Property 'returnedProp' does not exist on type 'boolean'. \ No newline at end of file + export let c = obj["prop"] `${(input) => ({ ...input })}` + c.returnedObjProp.x; + ~ +!!! error TS2339: Property 'x' does not exist on type '{}'. + c.returnedObjProp.y; + ~ +!!! error TS2339: Property 'y' does not exist on type '{}'. + c.returnedObjProp.z; + ~ +!!! error TS2339: Property 'z' does not exist on type '{}'. + + c = obj.prop `${(input) => ({ ...input })}` + c.returnedObjProp.x; + ~ +!!! error TS2339: Property 'x' does not exist on type '{}'. + c.returnedObjProp.y; + ~ +!!! error TS2339: Property 'y' does not exist on type '{}'. + c.returnedObjProp.z; + ~ +!!! error TS2339: Property 'z' does not exist on type '{}'. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js index 629571b4db0..9d2474da8be 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js @@ -31,19 +31,22 @@ export const b = g ` declare let obj: { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { - returnedObjProp: { - lastOne: T - } + returnedObjProp: T } } -export const c = obj["prop"] `${(input) => { ...input }}` -c.returnedProp.x; -c.returnedProp.y; -c.returnedProp.z; +export let c = obj["prop"] `${(input) => ({ ...input })}` +c.returnedObjProp.x; +c.returnedObjProp.y; +c.returnedObjProp.z; + +c = obj.prop `${(input) => ({ ...input })}` +c.returnedObjProp.x; +c.returnedObjProp.y; +c.returnedObjProp.z; //// [taggedTemplatesWithTypeArguments1.js] -export const a = f < Stuff > ` +export const a = f ` hello ${stuff => stuff.x} brave @@ -51,8 +54,7 @@ export const a = f < Stuff > ` world ${stuff => stuff.z} `; -export const b = g < Stuff, number, string, boolean; - > ` +export const b = g ` hello ${stuff => stuff.x} brave @@ -60,7 +62,11 @@ export const b = g < Stuff, number, string, boolean; world ${stuff => stuff.z} `; -export const c = obj["prop"] < Stuff > `${(input) => { input; }}`; -c.returnedProp.x; -c.returnedProp.y; -c.returnedProp.z; +export let c = obj["prop"] `${(input) => ({ ...input })}`; +c.returnedObjProp.x; +c.returnedObjProp.y; +c.returnedObjProp.z; +c = obj.prop `${(input) => ({ ...input })}`; +c.returnedObjProp.x; +c.returnedObjProp.y; +c.returnedObjProp.z; diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols index 85170aad228..c90089e50cc 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols @@ -25,6 +25,7 @@ interface Stuff { export const a = f ` >a : Symbol(a, Decl(taggedTemplatesWithTypeArguments1.ts, 8, 12)) >f : Symbol(f, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 0)) +>Stuff : Symbol(Stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 92)) hello ${stuff => stuff.x} @@ -74,9 +75,7 @@ declare function g( export const b = g ` >b : Symbol(b, Decl(taggedTemplatesWithTypeArguments1.ts, 21, 12)) >g : Symbol(g, Decl(taggedTemplatesWithTypeArguments1.ts, 15, 2)) ->number : Symbol(number, Decl(taggedTemplatesWithTypeArguments1.ts, 21, 25)) ->string : Symbol(string, Decl(taggedTemplatesWithTypeArguments1.ts, 21, 33)) ->boolean : Symbol(boolean, Decl(taggedTemplatesWithTypeArguments1.ts, 21, 41)) +>Stuff : Symbol(Stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 92)) hello ${stuff => stuff.x} @@ -108,29 +107,56 @@ declare let obj: { >T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 11)) >T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 11)) - returnedObjProp: { + returnedObjProp: T >returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) - - lastOne: T ->lastOne : Symbol(lastOne, Decl(taggedTemplatesWithTypeArguments1.ts, 32, 26)) >T : Symbol(T, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 11)) - } } } -export const c = obj["prop"] `${(input) => { ...input }}` ->c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 12)) +export let c = obj["prop"] `${(input) => ({ ...input })}` +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) >obj : Symbol(obj, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 11)) >"prop" : Symbol(prop, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 18)) ->input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 40)) ->input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 40)) +>Stuff : Symbol(Stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 92)) +>input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 38)) +>input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 38)) -c.returnedProp.x; ->c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 12)) +c.returnedObjProp.x; +>c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) +>returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) -c.returnedProp.y; ->c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 12)) +c.returnedObjProp.y; +>c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) +>returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) -c.returnedProp.z; ->c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 38, 12)) +c.returnedObjProp.z; +>c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) +>returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) + +c = obj.prop `${(input) => ({ ...input })}` +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) +>obj.prop : Symbol(prop, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 18)) +>obj : Symbol(obj, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 11)) +>prop : Symbol(prop, Decl(taggedTemplatesWithTypeArguments1.ts, 30, 18)) +>Stuff : Symbol(Stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 0, 92)) +>input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 41, 24)) +>input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 41, 24)) + +c.returnedObjProp.x; +>c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) +>returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) + +c.returnedObjProp.y; +>c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) +>returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) + +c.returnedObjProp.z; +>c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) +>returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types index 9999bb67bd8..74f916d0efa 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types @@ -23,35 +23,34 @@ interface Stuff { } export const a = f ` ->a : boolean ->f ` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : boolean ->fa : void +>f ` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : void >f : (strs: TemplateStringsArray, ...callbacks: ((x: T) => any)[]) => void ->Stuff : any +>Stuff : Stuff >` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : string hello ${stuff => stuff.x} ->stuff => stuff.x : (stuff: any) => any ->stuff : any +>stuff => stuff.x : (stuff: {}) => any +>stuff : {} >stuff.x : any ->stuff : any +>stuff : {} >x : any brave ${stuff => stuff.y} ->stuff => stuff.y : (stuff: any) => any ->stuff : any +>stuff => stuff.y : (stuff: {}) => any +>stuff : {} >stuff.y : any ->stuff : any +>stuff : {} >y : any world ${stuff => stuff.z} ->stuff => stuff.z : (stuff: any) => any ->stuff : any +>stuff => stuff.z : (stuff: {}) => any +>stuff : {} >stuff.z : any ->stuff : any +>stuff : {} >z : any `; @@ -85,48 +84,43 @@ declare function g( >V : V export const b = g ` ->b : boolean ->gb : any +>g ` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : any >g : (strs: TemplateStringsArray, t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V) => T | U | V ->Stuff : any ->number : any ->string : any ->boolean : any ->> ` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : boolean -> : any +>Stuff : Stuff >` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : string hello ${stuff => stuff.x} ->stuff => stuff.x : (stuff: any) => any ->stuff : any +>stuff => stuff.x : (stuff: {}) => any +>stuff : {} >stuff.x : any ->stuff : any +>stuff : {} >x : any brave ${stuff => stuff.y} ->stuff => stuff.y : (stuff: any) => any ->stuff : any +>stuff => stuff.y : (stuff: {}) => any +>stuff : {} >stuff.y : any ->stuff : any +>stuff : {} >y : any world ${stuff => stuff.z} ->stuff => stuff.z : (stuff: any) => any ->stuff : any +>stuff => stuff.z : (stuff: {}) => any +>stuff : {} >stuff.z : any ->stuff : any +>stuff : {} >z : any `; declare let obj: { ->obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: { lastOne: T; }; }; } +>obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; }; } prop: (strs: TemplateStringsArray, x: (input: T) => T) => { ->prop : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: { lastOne: T; }; } +>prop : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; } >T : T >strs : TemplateStringsArray >TemplateStringsArray : TemplateStringsArray @@ -135,47 +129,80 @@ declare let obj: { >T : T >T : T - returnedObjProp: { ->returnedObjProp : { lastOne: T; } - - lastOne: T ->lastOne : T + returnedObjProp: T +>returnedObjProp : T >T : T - } } } -export const c = obj["prop"] `${(input) => { ...input }}` ->c : boolean ->obj["prop"] `${(input) => { ...input }}` : boolean ->obj["prop"]obj["prop"] : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: { lastOne: T; }; } ->obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: { lastOne: T; }; }; } +export let c = obj["prop"] `${(input) => ({ ...input })}` +>c : { returnedObjProp: {}; } +>obj["prop"] `${(input) => ({ ...input })}` : { returnedObjProp: {}; } +>obj["prop"] : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; } +>obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; }; } >"prop" : "prop" ->Stuff : any ->`${(input) => { ...input }}` : string ->(input) => { ...input } : (input: any) => void ->input : any ->input : any +>Stuff : Stuff +>`${(input) => ({ ...input })}` : string +>(input) => ({ ...input }) : (input: {}) => {} +>input : {} +>({ ...input }) : {} +>{ ...input } : {} +>input : {} -c.returnedProp.x; ->c.returnedProp.x : any ->c.returnedProp : any ->c : boolean ->returnedProp : any +c.returnedObjProp.x; +>c.returnedObjProp.x : any +>c.returnedObjProp : {} +>c : { returnedObjProp: {}; } +>returnedObjProp : {} >x : any -c.returnedProp.y; ->c.returnedProp.y : any ->c.returnedProp : any ->c : boolean ->returnedProp : any +c.returnedObjProp.y; +>c.returnedObjProp.y : any +>c.returnedObjProp : {} +>c : { returnedObjProp: {}; } +>returnedObjProp : {} >y : any -c.returnedProp.z; ->c.returnedProp.z : any ->c.returnedProp : any ->c : boolean ->returnedProp : any +c.returnedObjProp.z; +>c.returnedObjProp.z : any +>c.returnedObjProp : {} +>c : { returnedObjProp: {}; } +>returnedObjProp : {} +>z : any + +c = obj.prop `${(input) => ({ ...input })}` +>c = obj.prop `${(input) => ({ ...input })}` : { returnedObjProp: {}; } +>c : { returnedObjProp: {}; } +>obj.prop `${(input) => ({ ...input })}` : { returnedObjProp: {}; } +>obj.prop : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; } +>obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; }; } +>prop : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; } +>Stuff : Stuff +>`${(input) => ({ ...input })}` : string +>(input) => ({ ...input }) : (input: {}) => {} +>input : {} +>({ ...input }) : {} +>{ ...input } : {} +>input : {} + +c.returnedObjProp.x; +>c.returnedObjProp.x : any +>c.returnedObjProp : {} +>c : { returnedObjProp: {}; } +>returnedObjProp : {} +>x : any + +c.returnedObjProp.y; +>c.returnedObjProp.y : any +>c.returnedObjProp : {} +>c : { returnedObjProp: {}; } +>returnedObjProp : {} +>y : any + +c.returnedObjProp.z; +>c.returnedObjProp.z : any +>c.returnedObjProp : {} +>c : { returnedObjProp: {}; } +>returnedObjProp : {} >z : any From 7aa916a5cb477e1c7a6361c642770d67bb38c4c6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:35:32 -0700 Subject: [PATCH 040/229] Strip away type arguments from tagged templates when emitting. --- src/compiler/factory.ts | 8 +++++--- src/compiler/transformers/ts.ts | 11 +++++++++++ src/compiler/visitor.ts | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 765c3c9cb4a..7dd7216725a 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1032,17 +1032,19 @@ namespace ts { : node; } - export function createTaggedTemplate(tag: Expression, template: TemplateLiteral) { + export function createTaggedTemplate(tag: Expression, typeArguments: NodeArray, template: TemplateLiteral) { const node = createSynthesizedNode(SyntaxKind.TaggedTemplateExpression); node.tag = parenthesizeForAccess(tag); + node.typeArguments = typeArguments; node.template = template; return node; } - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) { + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: NodeArray, template: TemplateLiteral) { return node.tag !== tag + || node.typeArguments !== typeArguments || node.template !== template - ? updateNode(createTaggedTemplate(tag, template), node) + ? updateNode(createTaggedTemplate(tag, typeArguments, template), node) : node; } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 6cb4be16c74..f29829d4607 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -502,6 +502,9 @@ namespace ts { case SyntaxKind.NewExpression: return visitNewExpression(node); + case SyntaxKind.TaggedTemplateExpression: + return visitTaggedTemplateExpression(node); + case SyntaxKind.NonNullExpression: // TypeScript non-null expressions are removed, but their subtrees are preserved. return visitNonNullExpression(node); @@ -2547,6 +2550,14 @@ namespace ts { visitNodes(node.arguments, visitor, isExpression)); } + function visitTaggedTemplateExpression(node: TaggedTemplateExpression) { + return updateTaggedTemplate( + node, + visitNode(node.tag, visitor, isExpression), + /*typeArguments*/ undefined, + visitNode(node.template, visitor, isExpression)); + } + /** * Determines whether to emit an enum declaration. * diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 7a70eb02e8e..284d870caa1 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -478,6 +478,7 @@ namespace ts { case SyntaxKind.TaggedTemplateExpression: return updateTaggedTemplate(node, visitNode((node).tag, visitor, isExpression), + visitNodes((node).typeArguments, visitor, isExpression), visitNode((node).template, visitor, isTemplateLiteral)); case SyntaxKind.TypeAssertionExpression: From 4785acb8cd6a5529c77e26320a98b5aaee962cb6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:35:42 -0700 Subject: [PATCH 041/229] Accepted baselines. --- tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++-- tests/baselines/reference/api/typescript.d.ts | 4 ++-- .../reference/taggedTemplatesWithTypeArguments1.js | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ae99f93ae1a..a250dcf6961 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3517,8 +3517,8 @@ declare namespace ts { function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray): CallExpression; function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; - function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + function createTaggedTemplate(tag: Expression, typeArguments: NodeArray, template: TemplateLiteral): TaggedTemplateExpression; + function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: NodeArray, template: TemplateLiteral): TaggedTemplateExpression; function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; function createParen(expression: Expression): ParenthesizedExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c419eceaf95..4e15b26a13d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3517,8 +3517,8 @@ declare namespace ts { function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray): CallExpression; function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; - function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; - function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + function createTaggedTemplate(tag: Expression, typeArguments: NodeArray, template: TemplateLiteral): TaggedTemplateExpression; + function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: NodeArray, template: TemplateLiteral): TaggedTemplateExpression; function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; function createParen(expression: Expression): ParenthesizedExpression; diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js index 9d2474da8be..b31d3270208 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.js @@ -46,7 +46,7 @@ c.returnedObjProp.y; c.returnedObjProp.z; //// [taggedTemplatesWithTypeArguments1.js] -export const a = f ` +export const a = f ` hello ${stuff => stuff.x} brave @@ -54,7 +54,7 @@ export const a = f ` world ${stuff => stuff.z} `; -export const b = g ` +export const b = g ` hello ${stuff => stuff.x} brave @@ -62,11 +62,11 @@ export const b = g ` world ${stuff => stuff.z} `; -export let c = obj["prop"] `${(input) => ({ ...input })}`; +export let c = obj["prop"] `${(input) => ({ ...input })}`; c.returnedObjProp.x; c.returnedObjProp.y; c.returnedObjProp.z; -c = obj.prop `${(input) => ({ ...input })}`; +c = obj.prop `${(input) => ({ ...input })}`; c.returnedObjProp.x; c.returnedObjProp.y; c.returnedObjProp.z; From 82e09c908e3cf80cea12d2eb05a458a9a2b87811 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:43:49 -0700 Subject: [PATCH 042/229] Perform checking and resolution of tagged template type arguments. --- src/compiler/checker.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d009a956c43..60fcf103041 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17749,7 +17749,11 @@ namespace ts { let typeArguments: NodeArray; - if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) { + if (isTaggedTemplate) { + typeArguments = (node as TaggedTemplateExpression).typeArguments; + forEach(typeArguments, checkSourceElement); + } + else if (!isDecorator && !isJsxOpeningOrSelfClosingElement) { typeArguments = (node).typeArguments; // We already perform checking on the type arguments on the class declaration itself. @@ -17866,7 +17870,7 @@ namespace ts { checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true); } else if (candidateForTypeArgumentError) { - checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression).typeArguments, /*reportErrors*/ true, fallbackError); + checkTypeArguments(candidateForTypeArgumentError, (node as CallExpression | TaggedTemplateExpression).typeArguments, /*reportErrors*/ true, fallbackError); } else if (typeArguments && every(signatures, sig => length(sig.typeParameters) !== typeArguments.length)) { diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments)); @@ -18660,6 +18664,7 @@ namespace ts { } function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type { + checkGrammarTypeArguments(node, node.typeArguments); if (languageVersion < ScriptTarget.ES2015) { checkExternalEmitHelpers(node, ExternalEmitHelpers.MakeTemplateObject); } From fe8615d0a8ebbffc55a5f177d638f46259e57bb7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 13 Apr 2018 23:44:07 -0700 Subject: [PATCH 043/229] Accepted baselines. --- ...ggedTemplatesWithTypeArguments1.errors.txt | 84 ---------- .../taggedTemplatesWithTypeArguments1.symbols | 24 +++ .../taggedTemplatesWithTypeArguments1.types | 154 +++++++++--------- 3 files changed, 101 insertions(+), 161 deletions(-) delete mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt deleted file mode 100644 index 6b732dbf4aa..00000000000 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.errors.txt +++ /dev/null @@ -1,84 +0,0 @@ -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(11,22): error TS2339: Property 'x' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(13,22): error TS2339: Property 'y' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(15,22): error TS2339: Property 'z' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(24,22): error TS2339: Property 'x' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(26,22): error TS2339: Property 'y' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(28,22): error TS2339: Property 'z' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(38,19): error TS2339: Property 'x' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(39,19): error TS2339: Property 'y' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(40,19): error TS2339: Property 'z' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(43,19): error TS2339: Property 'x' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(44,19): error TS2339: Property 'y' does not exist on type '{}'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts(45,19): error TS2339: Property 'z' does not exist on type '{}'. - - -==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments1.ts (12 errors) ==== - declare function f(strs: TemplateStringsArray, ...callbacks: Array<(x: T) => any>): void; - - interface Stuff { - x: number; - y: string; - z: boolean; - } - - export const a = f ` - hello - ${stuff => stuff.x} - ~ -!!! error TS2339: Property 'x' does not exist on type '{}'. - brave - ${stuff => stuff.y} - ~ -!!! error TS2339: Property 'y' does not exist on type '{}'. - world - ${stuff => stuff.z} - ~ -!!! error TS2339: Property 'z' does not exist on type '{}'. - `; - - declare function g( - strs: TemplateStringsArray, - t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V): T | U | V; - - export const b = g ` - hello - ${stuff => stuff.x} - ~ -!!! error TS2339: Property 'x' does not exist on type '{}'. - brave - ${stuff => stuff.y} - ~ -!!! error TS2339: Property 'y' does not exist on type '{}'. - world - ${stuff => stuff.z} - ~ -!!! error TS2339: Property 'z' does not exist on type '{}'. - `; - - declare let obj: { - prop: (strs: TemplateStringsArray, x: (input: T) => T) => { - returnedObjProp: T - } - } - - export let c = obj["prop"] `${(input) => ({ ...input })}` - c.returnedObjProp.x; - ~ -!!! error TS2339: Property 'x' does not exist on type '{}'. - c.returnedObjProp.y; - ~ -!!! error TS2339: Property 'y' does not exist on type '{}'. - c.returnedObjProp.z; - ~ -!!! error TS2339: Property 'z' does not exist on type '{}'. - - c = obj.prop `${(input) => ({ ...input })}` - c.returnedObjProp.x; - ~ -!!! error TS2339: Property 'x' does not exist on type '{}'. - c.returnedObjProp.y; - ~ -!!! error TS2339: Property 'y' does not exist on type '{}'. - c.returnedObjProp.z; - ~ -!!! error TS2339: Property 'z' does not exist on type '{}'. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols index c90089e50cc..798d2e18c68 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.symbols @@ -30,17 +30,23 @@ export const a = f ` hello ${stuff => stuff.x} >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 10, 6)) +>stuff.x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 10, 6)) +>x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) brave ${stuff => stuff.y} >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 12, 6)) +>stuff.y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 12, 6)) +>y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) world ${stuff => stuff.z} >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 14, 6)) +>stuff.z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 14, 6)) +>z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) `; @@ -80,17 +86,23 @@ export const b = g ` hello ${stuff => stuff.x} >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 23, 6)) +>stuff.x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 23, 6)) +>x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) brave ${stuff => stuff.y} >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 25, 6)) +>stuff.y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 25, 6)) +>y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) world ${stuff => stuff.z} >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 27, 6)) +>stuff.z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) >stuff : Symbol(stuff, Decl(taggedTemplatesWithTypeArguments1.ts, 27, 6)) +>z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) `; @@ -122,19 +134,25 @@ export let c = obj["prop"] `${(input) => ({ ...input })}` >input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 38)) c.returnedObjProp.x; +>c.returnedObjProp.x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) >c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) >c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) >returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) c.returnedObjProp.y; +>c.returnedObjProp.y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) >c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) >c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) >returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) c.returnedObjProp.z; +>c.returnedObjProp.z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) >c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) >c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) >returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) c = obj.prop `${(input) => ({ ...input })}` >c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) @@ -146,17 +164,23 @@ c = obj.prop `${(input) => ({ ...input })}` >input : Symbol(input, Decl(taggedTemplatesWithTypeArguments1.ts, 41, 24)) c.returnedObjProp.x; +>c.returnedObjProp.x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) >c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) >c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) >returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>x : Symbol(Stuff.x, Decl(taggedTemplatesWithTypeArguments1.ts, 2, 17)) c.returnedObjProp.y; +>c.returnedObjProp.y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) >c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) >c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) >returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>y : Symbol(Stuff.y, Decl(taggedTemplatesWithTypeArguments1.ts, 3, 14)) c.returnedObjProp.z; +>c.returnedObjProp.z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) >c.returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) >c : Symbol(c, Decl(taggedTemplatesWithTypeArguments1.ts, 36, 10)) >returnedObjProp : Symbol(returnedObjProp, Decl(taggedTemplatesWithTypeArguments1.ts, 31, 66)) +>z : Symbol(Stuff.z, Decl(taggedTemplatesWithTypeArguments1.ts, 4, 14)) diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types index 74f916d0efa..afa83c1b890 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments1.types @@ -31,27 +31,27 @@ export const a = f ` hello ${stuff => stuff.x} ->stuff => stuff.x : (stuff: {}) => any ->stuff : {} ->stuff.x : any ->stuff : {} ->x : any +>stuff => stuff.x : (stuff: Stuff) => number +>stuff : Stuff +>stuff.x : number +>stuff : Stuff +>x : number brave ${stuff => stuff.y} ->stuff => stuff.y : (stuff: {}) => any ->stuff : {} ->stuff.y : any ->stuff : {} ->y : any +>stuff => stuff.y : (stuff: Stuff) => string +>stuff : Stuff +>stuff.y : string +>stuff : Stuff +>y : string world ${stuff => stuff.z} ->stuff => stuff.z : (stuff: {}) => any ->stuff : {} ->stuff.z : any ->stuff : {} ->z : any +>stuff => stuff.z : (stuff: Stuff) => boolean +>stuff : Stuff +>stuff.z : boolean +>stuff : Stuff +>z : boolean `; @@ -84,35 +84,35 @@ declare function g( >V : V export const b = g ` ->b : any ->g ` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : any +>b : string | number | boolean +>g ` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : string | number | boolean >g : (strs: TemplateStringsArray, t: (i: Input) => T, u: (i: Input) => U, v: (i: Input) => V) => T | U | V >Stuff : Stuff >` hello ${stuff => stuff.x} brave ${stuff => stuff.y} world ${stuff => stuff.z}` : string hello ${stuff => stuff.x} ->stuff => stuff.x : (stuff: {}) => any ->stuff : {} ->stuff.x : any ->stuff : {} ->x : any +>stuff => stuff.x : (stuff: Stuff) => number +>stuff : Stuff +>stuff.x : number +>stuff : Stuff +>x : number brave ${stuff => stuff.y} ->stuff => stuff.y : (stuff: {}) => any ->stuff : {} ->stuff.y : any ->stuff : {} ->y : any +>stuff => stuff.y : (stuff: Stuff) => string +>stuff : Stuff +>stuff.y : string +>stuff : Stuff +>y : string world ${stuff => stuff.z} ->stuff => stuff.z : (stuff: {}) => any ->stuff : {} ->stuff.z : any ->stuff : {} ->z : any +>stuff => stuff.z : (stuff: Stuff) => boolean +>stuff : Stuff +>stuff.z : boolean +>stuff : Stuff +>z : boolean `; @@ -136,73 +136,73 @@ declare let obj: { } export let c = obj["prop"] `${(input) => ({ ...input })}` ->c : { returnedObjProp: {}; } ->obj["prop"] `${(input) => ({ ...input })}` : { returnedObjProp: {}; } +>c : { returnedObjProp: Stuff; } +>obj["prop"] `${(input) => ({ ...input })}` : { returnedObjProp: Stuff; } >obj["prop"] : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; } >obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; }; } >"prop" : "prop" >Stuff : Stuff >`${(input) => ({ ...input })}` : string ->(input) => ({ ...input }) : (input: {}) => {} ->input : {} ->({ ...input }) : {} ->{ ...input } : {} ->input : {} +>(input) => ({ ...input }) : (input: Stuff) => { x: number; y: string; z: boolean; } +>input : Stuff +>({ ...input }) : { x: number; y: string; z: boolean; } +>{ ...input } : { x: number; y: string; z: boolean; } +>input : Stuff c.returnedObjProp.x; ->c.returnedObjProp.x : any ->c.returnedObjProp : {} ->c : { returnedObjProp: {}; } ->returnedObjProp : {} ->x : any +>c.returnedObjProp.x : number +>c.returnedObjProp : Stuff +>c : { returnedObjProp: Stuff; } +>returnedObjProp : Stuff +>x : number c.returnedObjProp.y; ->c.returnedObjProp.y : any ->c.returnedObjProp : {} ->c : { returnedObjProp: {}; } ->returnedObjProp : {} ->y : any +>c.returnedObjProp.y : string +>c.returnedObjProp : Stuff +>c : { returnedObjProp: Stuff; } +>returnedObjProp : Stuff +>y : string c.returnedObjProp.z; ->c.returnedObjProp.z : any ->c.returnedObjProp : {} ->c : { returnedObjProp: {}; } ->returnedObjProp : {} ->z : any +>c.returnedObjProp.z : boolean +>c.returnedObjProp : Stuff +>c : { returnedObjProp: Stuff; } +>returnedObjProp : Stuff +>z : boolean c = obj.prop `${(input) => ({ ...input })}` ->c = obj.prop `${(input) => ({ ...input })}` : { returnedObjProp: {}; } ->c : { returnedObjProp: {}; } ->obj.prop `${(input) => ({ ...input })}` : { returnedObjProp: {}; } +>c = obj.prop `${(input) => ({ ...input })}` : { returnedObjProp: Stuff; } +>c : { returnedObjProp: Stuff; } +>obj.prop `${(input) => ({ ...input })}` : { returnedObjProp: Stuff; } >obj.prop : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; } >obj : { prop: (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; }; } >prop : (strs: TemplateStringsArray, x: (input: T) => T) => { returnedObjProp: T; } >Stuff : Stuff >`${(input) => ({ ...input })}` : string ->(input) => ({ ...input }) : (input: {}) => {} ->input : {} ->({ ...input }) : {} ->{ ...input } : {} ->input : {} +>(input) => ({ ...input }) : (input: Stuff) => { x: number; y: string; z: boolean; } +>input : Stuff +>({ ...input }) : { x: number; y: string; z: boolean; } +>{ ...input } : { x: number; y: string; z: boolean; } +>input : Stuff c.returnedObjProp.x; ->c.returnedObjProp.x : any ->c.returnedObjProp : {} ->c : { returnedObjProp: {}; } ->returnedObjProp : {} ->x : any +>c.returnedObjProp.x : number +>c.returnedObjProp : Stuff +>c : { returnedObjProp: Stuff; } +>returnedObjProp : Stuff +>x : number c.returnedObjProp.y; ->c.returnedObjProp.y : any ->c.returnedObjProp : {} ->c : { returnedObjProp: {}; } ->returnedObjProp : {} ->y : any +>c.returnedObjProp.y : string +>c.returnedObjProp : Stuff +>c : { returnedObjProp: Stuff; } +>returnedObjProp : Stuff +>y : string c.returnedObjProp.z; ->c.returnedObjProp.z : any ->c.returnedObjProp : {} ->c : { returnedObjProp: {}; } ->returnedObjProp : {} ->z : any +>c.returnedObjProp.z : boolean +>c.returnedObjProp : Stuff +>c : { returnedObjProp: Stuff; } +>returnedObjProp : Stuff +>z : boolean From 02b8160b41636a3a742f5e4de0b13d9415ef2819 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Sun, 15 Apr 2018 01:23:27 +1000 Subject: [PATCH 044/229] store lastToken --- src/services/preProcess.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 3cf38eecd6e..208d276a73c 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -13,20 +13,20 @@ namespace ts { const importedFiles: FileReference[] = []; let ambientExternalModules: { ref: FileReference, depth: number }[]; let braceNesting = 0; - let lastTokenWasDot = false; + let lastToken: SyntaxKind = null; // assume that text represent an external module if it contains at least one top level import/export // ambient modules that are found inside external modules are interpreted as module augmentations let externalModule = false; function nextToken() { const token = scanner.scan(); + lastToken = token; if (token === SyntaxKind.OpenBraceToken) { braceNesting++; } else if (token === SyntaxKind.CloseBraceToken) { braceNesting--; } - lastTokenWasDot = token === SyntaxKind.DotToken; return token; } @@ -79,6 +79,7 @@ namespace ts { * Returns true if at least one token was consumed from the stream */ function tryConsumeImport(): boolean { + const lastTokenWasDot = lastToken === SyntaxKind.DotToken; let token = scanner.getToken(); if (token === SyntaxKind.ImportKeyword && !lastTokenWasDot) { token = nextToken(); From f4fa2eb28e014ebd42f6a368ab5b91ed7a128bf5 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Sun, 15 Apr 2018 01:51:01 +1000 Subject: [PATCH 045/229] undefined instead of null --- src/services/preProcess.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 208d276a73c..f0958193ceb 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -13,7 +13,7 @@ namespace ts { const importedFiles: FileReference[] = []; let ambientExternalModules: { ref: FileReference, depth: number }[]; let braceNesting = 0; - let lastToken: SyntaxKind = null; + let lastToken: SyntaxKind; // assume that text represent an external module if it contains at least one top level import/export // ambient modules that are found inside external modules are interpreted as module augmentations let externalModule = false; From c64c1c93954ec3f13443ce08ff57d4bf93dbff4d Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Sun, 15 Apr 2018 03:30:47 +1000 Subject: [PATCH 046/229] fix up --- src/services/preProcess.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index f0958193ceb..f63f84b52ba 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -13,14 +13,12 @@ namespace ts { const importedFiles: FileReference[] = []; let ambientExternalModules: { ref: FileReference, depth: number }[]; let braceNesting = 0; - let lastToken: SyntaxKind; // assume that text represent an external module if it contains at least one top level import/export // ambient modules that are found inside external modules are interpreted as module augmentations let externalModule = false; function nextToken() { const token = scanner.scan(); - lastToken = token; if (token === SyntaxKind.OpenBraceToken) { braceNesting++; } @@ -79,9 +77,8 @@ namespace ts { * Returns true if at least one token was consumed from the stream */ function tryConsumeImport(): boolean { - const lastTokenWasDot = lastToken === SyntaxKind.DotToken; let token = scanner.getToken(); - if (token === SyntaxKind.ImportKeyword && !lastTokenWasDot) { + if (token === SyntaxKind.ImportKeyword) { token = nextToken(); if (token === SyntaxKind.OpenParenToken) { token = nextToken(); @@ -300,9 +297,14 @@ namespace ts { // AnySymbol.import("mod") while (true) { - if (scanner.getToken() === SyntaxKind.EndOfFileToken) { + const token = scanner.getToken(); + if (token === SyntaxKind.EndOfFileToken) { break; } + if (token === SyntaxKind.DotToken) { + nextToken(); // jump over anything directly following the dot + nextToken(); + } // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || From 299002d597eed0daa56a444730ea5cdaff682ac3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 14 Apr 2018 11:53:27 -0700 Subject: [PATCH 047/229] Fix spacing. --- src/compiler/commandLineParser.ts | 16 ++++++++-------- src/compiler/tsc.ts | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 252ea9e8df0..2de922b4159 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -56,14 +56,14 @@ namespace ts { category: Diagnostics.Command_line_Options, description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, - { - name: "diagnosticStyle", - type: createMapFromTemplate({ - auto: DiagnosticStyle.Auto, - pretty: DiagnosticStyle.Pretty, - simple: DiagnosticStyle.Simple, - }), - }, + { + name: "diagnosticStyle", + type: createMapFromTemplate({ + auto: DiagnosticStyle.Auto, + pretty: DiagnosticStyle.Pretty, + simple: DiagnosticStyle.Simple, + }), + }, { name: "preserveWatchOutput", type: "boolean", diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 5012b73e98a..56c3c323f30 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -27,7 +27,7 @@ namespace ts { function shouldBePretty(options: CompilerOptions) { if ((typeof options.pretty === "undefined" && typeof options.diagnosticStyle === "undefined") || options.diagnosticStyle === DiagnosticStyle.Auto) { return !!sys.writeOutputIsTty && sys.writeOutputIsTty(); - } + } return options.diagnosticStyle === DiagnosticStyle.Pretty || options.pretty; } From 4dc9db1e70852277fe58da22b1797cbdd8fe50c6 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Sun, 15 Apr 2018 11:27:51 +1000 Subject: [PATCH 048/229] detect nested non-imports --- .../unittests/services/preProcessFile.ts | 13 ++++++++++++ src/services/preProcess.ts | 21 ++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/harness/unittests/services/preProcessFile.ts b/src/harness/unittests/services/preProcessFile.ts index f68af84f759..76b1e4f05a6 100644 --- a/src/harness/unittests/services/preProcessFile.ts +++ b/src/harness/unittests/services/preProcessFile.ts @@ -72,6 +72,19 @@ describe("PreProcessFile:", () => { }); }), + it("Do not return reference path of nested non-imports", () => { + test("a.b.import('c');", + /*readImportFile*/ true, + /*detectJavaScriptImports*/ false, + { + referencedFiles: [], + importedFiles: [], + typeReferenceDirectives: [], + ambientExternalModules: undefined, + isLibFile: false + }); + }), + it("Correctly return imported files", () => { test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");", /*readImportFile*/ true, diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index f63f84b52ba..a1cb4676038 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -12,20 +12,25 @@ namespace ts { }; const importedFiles: FileReference[] = []; let ambientExternalModules: { ref: FileReference, depth: number }[]; + let lastToken: SyntaxKind; + let currentToken: SyntaxKind; let braceNesting = 0; // assume that text represent an external module if it contains at least one top level import/export // ambient modules that are found inside external modules are interpreted as module augmentations let externalModule = false; function nextToken() { - const token = scanner.scan(); - if (token === SyntaxKind.OpenBraceToken) { + if (currentToken) { + lastToken = currentToken; + } + currentToken = scanner.scan(); + if (currentToken === SyntaxKind.OpenBraceToken) { braceNesting++; } - else if (token === SyntaxKind.CloseBraceToken) { + else if (currentToken === SyntaxKind.CloseBraceToken) { braceNesting--; } - return token; + return currentToken; } function getFileReference() { @@ -77,6 +82,9 @@ namespace ts { * Returns true if at least one token was consumed from the stream */ function tryConsumeImport(): boolean { + if (lastToken === SyntaxKind.DotToken) { + return false; + } let token = scanner.getToken(); if (token === SyntaxKind.ImportKeyword) { token = nextToken(); @@ -295,16 +303,13 @@ namespace ts { // Do not look for: // AnySymbol.import("mod") + // AnySymbol.nested.import("mod") while (true) { const token = scanner.getToken(); if (token === SyntaxKind.EndOfFileToken) { break; } - if (token === SyntaxKind.DotToken) { - nextToken(); // jump over anything directly following the dot - nextToken(); - } // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || From a3311edb4a65a9c80d43ba7beb75bef16485a054 Mon Sep 17 00:00:00 2001 From: Joscha Feth Date: Sun, 15 Apr 2018 11:30:37 +1000 Subject: [PATCH 049/229] revert change --- src/services/preProcess.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index a1cb4676038..7b802301204 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -306,8 +306,7 @@ namespace ts { // AnySymbol.nested.import("mod") while (true) { - const token = scanner.getToken(); - if (token === SyntaxKind.EndOfFileToken) { + if (scanner.getToken() === SyntaxKind.EndOfFileToken) { break; } From c344e6d0bab6832cd97f74caf7be7368de823e6a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Apr 2018 17:10:05 -1000 Subject: [PATCH 050/229] Fixes and improvements to indexed access type relationships --- src/compiler/checker.ts | 130 ++++++++++++++++++++-------------------- src/server/utilities.ts | 2 +- 2 files changed, 67 insertions(+), 65 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9abf5ec0277..18f9812844c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6268,18 +6268,10 @@ namespace ts { } function getConstraintOfIndexedAccess(type: IndexedAccessType) { - const transformed = getSimplifiedIndexedAccessType(type); - if (transformed) { - return transformed; - } - const baseObjectType = getBaseConstraintOfType(type.objectType); - const baseIndexType = getBaseConstraintOfType(type.indexType); - if (baseIndexType === stringType && !getIndexInfoOfType(baseObjectType || type.objectType, IndexKind.String)) { - // getIndexedAccessType returns `any` for X[string] where X doesn't have an index signature. - // to avoid this, return `undefined`. - return undefined; - } - return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; + const objectType = getBaseConstraintOfType(type.objectType) || type.objectType; + const indexType = getBaseConstraintOfType(type.indexType) || type.indexType; + const constraint = !isGenericObjectType(objectType) && !isGenericIndexType(indexType) ? getIndexedAccessType(objectType, indexType) : undefined; + return constraint && constraint !== unknownType ? constraint : undefined; } function getDefaultConstraintOfConditionalType(type: ConditionalType) { @@ -6326,7 +6318,7 @@ namespace ts { function getBaseConstraintOfType(type: Type): Type { const constraint = getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type); if (!constraint && type.flags & TypeFlags.Index) { - return stringType; + return keyofConstraintType; } return constraint; } @@ -6361,7 +6353,7 @@ namespace ts { circular = true; return undefined; } - const result = computeBaseConstraint(t); + const result = computeBaseConstraint(getSimplifiedType(t)); if (!popTypeResolution()) { circular = true; return undefined; @@ -6390,13 +6382,9 @@ namespace ts { undefined; } if (t.flags & TypeFlags.Index) { - return stringType; + return keyofConstraintType; } if (t.flags & TypeFlags.IndexedAccess) { - const transformed = getSimplifiedIndexedAccessType(t); - if (transformed) { - return getBaseConstraint(transformed); - } const baseObjectType = getBaseConstraint((t).objectType); const baseIndexType = getBaseConstraint((t).indexType); const baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; @@ -6520,26 +6508,30 @@ namespace ts { if (props.length === 1 && !(checkFlags & CheckFlags.Partial)) { return props[0]; } - const propTypes: Type[] = []; - const declarations: Declaration[] = []; + let declarations: Declaration[]; let commonType: Type; + let nameType: Type; + let propTypes: Type[] = []; + let first = true; for (const prop of props) { - if (prop.declarations) { - addRange(declarations, prop.declarations); - } + declarations = addRange(declarations, prop.declarations); const type = getTypeOfSymbol(prop); - if (!commonType) { + if (first) { commonType = type; + nameType = prop.nameType; + first = false; } - else if (type !== commonType) { + else { + if (type !== commonType) { checkFlags |= CheckFlags.HasNonUniformType; } + } propTypes.push(type); } - // !!! const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags); result.containingType = containingType; result.declarations = declarations; + result.nameType = nameType; result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes); return result; } @@ -8151,9 +8143,8 @@ namespace ts { maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : - type.flags & TypeFlags.Any ? keyofConstraintType : - keyofStringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : - getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : + type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? keyofConstraintType : + keyofStringsOnly ? getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol); } @@ -8256,9 +8247,8 @@ namespace ts { else { error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); } - return unknownType; } - return anyType; + return unknownType; } function isGenericObjectType(type: Type): boolean { @@ -8285,8 +8275,12 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Mapped && getTemplateTypeFromMappedType(type as MappedType) === neverType; } + function getSimplifiedType(type: Type): Type { + return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(type) : type; + } + // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return - // undefined if no transformation is possible. + // the type itself if no transformation is possible. function getSimplifiedIndexedAccessType(type: IndexedAccessType): Type { const objectType = type.objectType; if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType)) { @@ -8306,7 +8300,7 @@ namespace ts { } } return getUnionType([ - getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), + getSimplifiedType(getIndexedAccessType(getIntersectionType(regularTypes), type.indexType)), getIntersectionType(stringIndexTypes) ]); } @@ -8316,13 +8310,13 @@ namespace ts { // eventually anyway, but it easier to reason about. if (some((objectType).types, isMappedTypeToNever)) { const nonNeverTypes = filter((objectType).types, t => !isMappedTypeToNever(t)); - return getIndexedAccessType(getIntersectionType(nonNeverTypes), type.indexType); + return getSimplifiedType(getIndexedAccessType(getIntersectionType(nonNeverTypes), type.indexType)); } } - // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we - // construct the type Box. + // construct the type Box. We do not further simplify the result because mapped types can be recursive + // and we might never terminate. if (isGenericMappedType(objectType)) { return substituteIndexedMappedType(objectType, type); } @@ -8332,7 +8326,7 @@ namespace ts { return substituteIndexedMappedType(constraint, type); } } - return undefined; + return type; } function substituteIndexedMappedType(objectType: MappedType, type: IndexedAccessType) { @@ -9887,6 +9881,12 @@ namespace ts { if (target.flags & TypeFlags.Substitution) { target = (target).typeVariable; } + if (source.flags & TypeFlags.IndexedAccess) { + source = getSimplifiedType(source); + } + if (target.flags & TypeFlags.IndexedAccess) { + target = getSimplifiedType(target); + } // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases if (source === target) return Ternary.True; @@ -10346,9 +10346,9 @@ namespace ts { } } else if (target.flags & TypeFlags.IndexedAccess) { - // A type S is related to a type T[K] if S is related to A[K], where K is string-like and - // A is the apparent type of T. - const constraint = getConstraintForRelation(target); + // A type S is related to a type T[K] if S is related to C, where C is the + // constraint of T[K] + const constraint = getConstraintForRelation(target); if (constraint) { if (result = isRelatedTo(source, constraint, reportErrors)) { errorInfo = saveErrorInfo; @@ -10361,21 +10361,21 @@ namespace ts { const template = getTemplateTypeFromMappedType(target); const modifiers = getMappedTypeModifiers(target); if (!(modifiers & MappedTypeModifiers.ExcludeOptional)) { - if (template.flags & TypeFlags.IndexedAccess && (template).objectType === source && - (template).indexType === getTypeParameterFromMappedType(target)) { - return Ternary.True; - } - // A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X. - if (!isGenericMappedType(source) && getConstraintTypeFromMappedType(target) === getIndexType(source)) { - const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target)); - const templateType = getTemplateTypeFromMappedType(target); - if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) { - errorInfo = saveErrorInfo; - return result; + if (template.flags & TypeFlags.IndexedAccess && (template).objectType === source && + (template).indexType === getTypeParameterFromMappedType(target)) { + return Ternary.True; + } + // A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X. + if (!isGenericMappedType(source) && getConstraintTypeFromMappedType(target) === getIndexType(source)) { + const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target)); + const templateType = getTemplateTypeFromMappedType(target); + if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) { + errorInfo = saveErrorInfo; + return result; + } } } } - } if (source.flags & TypeFlags.TypeParameter) { let constraint = getConstraintForRelation(source); @@ -10393,16 +10393,8 @@ namespace ts { } } else if (source.flags & TypeFlags.IndexedAccess) { - // A type S[K] is related to a type T if A[K] is related to T, where K is string-like and - // A is the apparent type of S. - const constraint = getConstraintForRelation(source); - if (constraint) { - if (result = isRelatedTo(constraint, target, reportErrors)) { - errorInfo = saveErrorInfo; - return result; - } - } - else if (target.flags & TypeFlags.IndexedAccess) { + if (target.flags & TypeFlags.IndexedAccess) { + // A type S[K] is related to a type T[J] if S is related to T and K is related to J. if (result = isRelatedTo((source).objectType, (target).objectType, reportErrors)) { result &= isRelatedTo((source).indexType, (target).indexType, reportErrors); } @@ -10411,6 +10403,15 @@ namespace ts { return result; } } + // A type S[K] is related to a type T if C is related to T, where C is the + // constraint of S[K]. + const constraint = getConstraintForRelation(source); + if (constraint) { + if (result = isRelatedTo(constraint, target, reportErrors)) { + errorInfo = saveErrorInfo; + return result; + } + } } else if (source.flags & TypeFlags.Index) { if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) { @@ -19917,7 +19918,8 @@ namespace ts { // this a literal context for literals of that primitive type. For example, given a // type parameter 'T extends string', infer string literal types for T. const constraint = getBaseConstraintOfType(contextualType) || emptyObjectType; - return constraint.flags & TypeFlags.String && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) || + return constraint === keyofConstraintType && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol) || + constraint.flags & TypeFlags.String && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) || constraint.flags & TypeFlags.Number && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) || constraint.flags & TypeFlags.Boolean && maybeTypeOfKind(candidateType, TypeFlags.BooleanLiteral) || constraint.flags & TypeFlags.ESSymbol && maybeTypeOfKind(candidateType, TypeFlags.UniqueESSymbol) || diff --git a/src/server/utilities.ts b/src/server/utilities.ts index e2329b868e3..ff7fa25af0f 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -86,7 +86,7 @@ namespace ts.server { export function mergeMapLikes(target: T, source: Partial): void { for (const key in source) { if (hasProperty(source, key)) { - target[key] = source[key]; + target[key] = (source)[key]; } } } From 6c60f7e2431b2c7cf70a99b0aaea32feb6dbe470 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 14 Apr 2018 17:16:07 -1000 Subject: [PATCH 051/229] Accept new baselines --- .../reference/conditionalTypes1.errors.txt | 162 +++++------------- .../reference/keyofAndIndexedAccess.types | 4 +- .../limitDeepInstantiations.errors.txt | 5 +- .../reference/mappedTypeErrors2.errors.txt | 10 +- .../mappedTypeRelationships.errors.txt | 80 +++++---- .../reference/recursiveTypeRelations.types | 2 +- 6 files changed, 92 insertions(+), 171 deletions(-) diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index acb72d2cb56..7ba3a2aa934 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -5,9 +5,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(17,5): error TS23 tests/cases/conformance/types/conditional/conditionalTypes1.ts(18,9): error TS2322: Type 'T' is not assignable to type 'string'. Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(24,5): error TS2322: Type 'Partial[keyof T]' is not assignable to type 'NonNullable[keyof T]>'. - Type 'T[keyof T] | undefined' is not assignable to type 'NonNullable[keyof T]>'. - Type 'undefined' is not assignable to type 'NonNullable[keyof T]>'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(24,5): error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'NonNullable[keyof T]>'. + Type 'undefined' is not assignable to type 'NonNullable[keyof T]>'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(29,5): error TS2322: Type 'T["x"]' is not assignable to type 'NonNullable'. Type 'string | undefined' is not assignable to type 'NonNullable'. Type 'undefined' is not assignable to type 'NonNullable'. @@ -17,65 +16,25 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(30,9): error TS23 tests/cases/conformance/types/conditional/conditionalTypes1.ts(103,5): error TS2322: Type 'Pick' is not assignable to type 'T'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(104,5): error TS2322: Type 'Pick' is not assignable to type 'T'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(106,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. - Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'keyof T' is not assignable to type 'never'. - Type 'string | number | symbol' is not assignable to type 'never'. - Type 'string' is not assignable to type 'never'. + Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'never'. + Type 'string | number | symbol' is not assignable to type 'never'. + Type 'string' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(108,5): error TS2322: Type 'Pick' is not assignable to type 'Pick'. - Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'keyof T' is not assignable to type 'never'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(115,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. - Type 'keyof T' is not assignable to type 'never'. - Type 'string | number | symbol' is not assignable to type 'never'. - Type 'string' is not assignable to type 'never'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(116,5): error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -tests/cases/conformance/types/conditional/conditionalTypes1.ts(117,5): error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. - Type 'keyof T' is not assignable to type 'never'. + Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'never'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(114,5): error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(115,5): error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. + Type 'keyof T' is not assignable to type 'never'. + Type 'string | number | symbol' is not assignable to type 'never'. + Type 'string' is not assignable to type 'never'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(116,5): error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +tests/cases/conformance/types/conditional/conditionalTypes1.ts(117,5): error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. + Type 'keyof T' is not assignable to type 'never'. tests/cases/conformance/types/conditional/conditionalTypes1.ts(134,10): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property. tests/cases/conformance/types/conditional/conditionalTypes1.ts(135,5): error TS2542: Index signature in type 'DeepReadonlyArray' only permits reading. tests/cases/conformance/types/conditional/conditionalTypes1.ts(136,22): error TS2540: Cannot assign to 'id' because it is a constant or a read-only property. @@ -129,9 +88,8 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS x = y; y = x; // Error ~ -!!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'NonNullable[keyof T]>'. -!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'NonNullable[keyof T]>'. -!!! error TS2322: Type 'undefined' is not assignable to type 'NonNullable[keyof T]>'. +!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'NonNullable[keyof T]>'. +!!! error TS2322: Type 'undefined' is not assignable to type 'NonNullable[keyof T]>'. } function f4(x: T["x"], y: NonNullable) { @@ -228,38 +186,16 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS y = z; // Error ~ !!! error TS2322: Type 'Pick' is not assignable to type 'Pick'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'. -!!! error TS2322: Type 'string' is not assignable to type 'never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. z = x; z = y; // Error ~ !!! error TS2322: Type 'Pick' is not assignable to type 'Pick'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. } function f8(x: keyof T, y: FunctionPropertyNames, z: NonFunctionPropertyNames) { @@ -267,42 +203,24 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS x = z; y = x; // Error ~ -!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. y = z; // Error ~ -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'. -!!! error TS2322: Type 'string' is not assignable to type 'never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? never : keyof T' is not assignable to type 'T[keyof T] extends Function ? keyof T : never'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'never'. +!!! error TS2322: Type 'string' is not assignable to type 'never'. z = x; // Error ~ -!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'string' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. z = y; // Error ~ -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'keyof T' is not assignable to type '{ [K in keyof T]: T[K] extends Function ? never : K; }[keyof T]'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type '{ [K in keyof T]: T[K] extends Function ? K : never; }[keyof T]' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. +!!! error TS2322: Type 'T[keyof T] extends Function ? keyof T : never' is not assignable to type 'T[keyof T] extends Function ? never : keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'never'. } type DeepReadonly = diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 4e41b58e664..7e2d80d6b9c 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -92,7 +92,7 @@ type K11 = keyof Shape[]; // "length" | "toString" | ... >Shape : Shape type K12 = keyof Dictionary; // string ->K12 : string | number +>K12 : string | number | symbol >Dictionary : Dictionary >Shape : Shape @@ -136,7 +136,7 @@ type K20 = KeyOf; // "name" | "width" | "height" | "visible" >Shape : Shape type K21 = KeyOf>; // string ->K21 : string | number +>K21 : string | number | symbol >KeyOf : keyof T >Dictionary : Dictionary >Shape : Shape diff --git a/tests/baselines/reference/limitDeepInstantiations.errors.txt b/tests/baselines/reference/limitDeepInstantiations.errors.txt index 70718199d2b..99ff4c789f4 100644 --- a/tests/baselines/reference/limitDeepInstantiations.errors.txt +++ b/tests/baselines/reference/limitDeepInstantiations.errors.txt @@ -1,8 +1,7 @@ tests/cases/compiler/limitDeepInstantiations.ts(3,35): error TS2502: '"true"' is referenced directly or indirectly in its own type annotation. -tests/cases/compiler/limitDeepInstantiations.ts(5,13): error TS2344: Type '"false"' does not satisfy the constraint '"true"'. -==== tests/cases/compiler/limitDeepInstantiations.ts (2 errors) ==== +==== tests/cases/compiler/limitDeepInstantiations.ts (1 errors) ==== // Repro from #14837 type Foo = { "true": Foo> }[T]; @@ -10,6 +9,4 @@ tests/cases/compiler/limitDeepInstantiations.ts(5,13): error TS2344: Type '"fals !!! error TS2502: '"true"' is referenced directly or indirectly in its own type annotation. let f1: Foo<"true", {}>; let f2: Foo<"false", {}>; - ~~~~~~~ -!!! error TS2344: Type '"false"' does not satisfy the constraint '"true"'. \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeErrors2.errors.txt b/tests/baselines/reference/mappedTypeErrors2.errors.txt index 18bc7cc7239..9178731d189 100644 --- a/tests/baselines/reference/mappedTypeErrors2.errors.txt +++ b/tests/baselines/reference/mappedTypeErrors2.errors.txt @@ -1,10 +1,13 @@ tests/cases/conformance/types/mapped/mappedTypeErrors2.ts(9,30): error TS2536: Type 'K' cannot be used to index type 'T1'. tests/cases/conformance/types/mapped/mappedTypeErrors2.ts(13,30): error TS2536: Type 'K' cannot be used to index type 'T3'. +tests/cases/conformance/types/mapped/mappedTypeErrors2.ts(15,38): error TS2536: Type 'S' cannot be used to index type '{ [key in AB[S]]: true; }'. +tests/cases/conformance/types/mapped/mappedTypeErrors2.ts(15,47): error TS2322: Type 'AB[S]' is not assignable to type 'string | number | symbol'. + Type 'AB[S]' is not assignable to type 'symbol'. tests/cases/conformance/types/mapped/mappedTypeErrors2.ts(15,47): error TS2536: Type 'S' cannot be used to index type 'AB'. tests/cases/conformance/types/mapped/mappedTypeErrors2.ts(17,49): error TS2536: Type 'L' cannot be used to index type '{ [key in AB[S]]: true; }'. -==== tests/cases/conformance/types/mapped/mappedTypeErrors2.ts (4 errors) ==== +==== tests/cases/conformance/types/mapped/mappedTypeErrors2.ts (6 errors) ==== // Repros from #17238 type AB = { @@ -24,6 +27,11 @@ tests/cases/conformance/types/mapped/mappedTypeErrors2.ts(17,49): error TS2536: !!! error TS2536: Type 'K' cannot be used to index type 'T3'. type T5 = {[key in AB[S]]: true}[S]; // Error + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2536: Type 'S' cannot be used to index type '{ [key in AB[S]]: true; }'. + ~~~~~ +!!! error TS2322: Type 'AB[S]' is not assignable to type 'string | number | symbol'. +!!! error TS2322: Type 'AB[S]' is not assignable to type 'symbol'. ~~~~~ !!! error TS2536: Type 'S' cannot be used to index type 'AB'. diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index 26618cc15db..60a06e000c2 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -10,29 +10,27 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(25,5): error TS2 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,12): error TS2536: Type 'K' cannot be used to index type 'T'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(30,5): error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. - Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. - Type 'undefined' is not assignable to type 'T[keyof T]'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(35,5): error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. - Type 'T[K] | undefined' is not assignable to type 'T[K]'. - Type 'undefined' is not assignable to type 'T[K]'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. - Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. - Type 'undefined' is not assignable to type 'T[keyof T]'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. - Type 'U[K] | undefined' is not assignable to type 'T[K]'. - Type 'undefined' is not assignable to type 'T[K]'. +tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(30,5): error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. + Type 'undefined' is not assignable to type 'T[keyof T]'. +tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(35,5): error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'. + Type 'undefined' is not assignable to type 'T[K]'. +tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. + Type 'undefined' is not assignable to type 'T[keyof T]'. +tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. + Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. + Type 'T' is not assignable to type 'U'. +tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. + Type 'undefined' is not assignable to type 'T[K]'. +tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. + Type 'T[K]' is not assignable to type 'U[K]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(51,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly' only permits reading. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'Readonly[keyof T]'. - Type 'T' is not assignable to type 'Readonly'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T' is not assignable to type 'U'. +tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2542: Index signature in type 'Readonly' only permits reading. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2322: Type 'T[K]' is not assignable to type 'Readonly[K]'. - Type 'T' is not assignable to type 'Readonly'. - Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T' is not assignable to type 'U'. +tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(72,5): error TS2322: Type 'Partial' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(78,5): error TS2322: Type 'Partial' is not assignable to type 'Partial'. @@ -62,7 +60,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS Type 'T' is not assignable to type 'U'. -==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (28 errors) ==== +==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (30 errors) ==== function f1(x: T, k: keyof T) { return x[k]; } @@ -114,37 +112,41 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS function f10(x: T, y: Partial, k: keyof T) { x[k] = y[k]; // Error ~~~~ -!!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. -!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. +!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. +!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. y[k] = x[k]; } function f11(x: T, y: Partial, k: K) { x[k] = y[k]; // Error ~~~~ -!!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. +!!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'. +!!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. y[k] = x[k]; } function f12(x: T, y: Partial, k: keyof T) { x[k] = y[k]; // Error ~~~~ -!!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. -!!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. +!!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. +!!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. y[k] = x[k]; // Error + ~~~~ +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f13(x: T, y: Partial, k: K) { x[k] = y[k]; // Error ~~~~ -!!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. +!!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. +!!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. y[k] = x[k]; // Error + ~~~~ +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f20(x: T, y: Readonly, k: keyof T) { @@ -165,10 +167,8 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS x[k] = y[k]; y[k] = x[k]; // Error ~~~~ -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'Readonly[keyof T]'. -!!! error TS2322: Type 'T' is not assignable to type 'Readonly'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2542: Index signature in type 'Readonly' only permits reading. } @@ -177,10 +177,8 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS x[k] = y[k]; y[k] = x[k]; // Error ~~~~ -!!! error TS2322: Type 'T[K]' is not assignable to type 'Readonly[K]'. -!!! error TS2322: Type 'T' is not assignable to type 'Readonly'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2542: Index signature in type 'Readonly' only permits reading. } diff --git a/tests/baselines/reference/recursiveTypeRelations.types b/tests/baselines/reference/recursiveTypeRelations.types index b844031c0d1..f3d56637b18 100644 --- a/tests/baselines/reference/recursiveTypeRelations.types +++ b/tests/baselines/reference/recursiveTypeRelations.types @@ -97,7 +97,7 @@ export function css(styles: S, ...classNam if (typeof arg == "object") { >typeof arg == "object" : boolean >typeof arg : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" ->arg : object & { [K in keyof S]?: boolean; } +>arg : keyof S | (object & { [K in keyof S]?: boolean; }) >"object" : "object" return Object.keys(arg).reduce((obj: ClassNameObject, key: keyof S) => { From 6107e05e8cdeefc598d49ec10f21c61dc325a0e2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sun, 15 Apr 2018 15:56:59 -0700 Subject: [PATCH 052/229] Added test for tagged templates in new expressions. --- .../taggedTemplatesWithTypeArguments2.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts diff --git a/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts new file mode 100644 index 00000000000..9c9bb8ee938 --- /dev/null +++ b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts @@ -0,0 +1,20 @@ +// @target: esnext +// @strict: true + +export interface SomethingTaggable { + (t: TemplateStringsArray, ...args: T[]): SomethingNewable; +} + +export interface SomethingNewable { + new (...args: T[]): any; +} + +declare const tag: SomethingTaggable; + +const a = new tag `${100} ${200}`("hello", "world"); + +const b = new tag `${"hello"} ${"world"}`(100, 200); + +const c = new tag `${100} ${200}`("hello", "world"); + +const d = new tag `${"hello"} ${"world"}`(100, 200); From 2510c19fbd64baba32d9b4c656c9902163fb10d7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sun, 15 Apr 2018 15:59:23 -0700 Subject: [PATCH 053/229] Accepted baselines. --- ...ggedTemplatesWithTypeArguments2.errors.txt | 66 +++++++++++++++++ .../taggedTemplatesWithTypeArguments2.js | 25 +++++++ .../taggedTemplatesWithTypeArguments2.symbols | 42 +++++++++++ .../taggedTemplatesWithTypeArguments2.types | 70 +++++++++++++++++++ 4 files changed, 203 insertions(+) create mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt create mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments2.js create mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols create mode 100644 tests/baselines/reference/taggedTemplatesWithTypeArguments2.types diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt new file mode 100644 index 00000000000..958fb6715d1 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt @@ -0,0 +1,66 @@ +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,11): error TS2350: Only a void function can be called with the 'new' keyword. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,27): error TS1005: '(' expected. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,27): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,60): error TS1005: ')' expected. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,11): error TS2350: Only a void function can be called with the 'new' keyword. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,27): error TS1005: '(' expected. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,27): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,68): error TS1005: ')' expected. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,11): error TS2350: Only a void function can be called with the 'new' keyword. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,27): error TS1005: '(' expected. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,27): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,68): error TS1005: ')' expected. + + +==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (15 errors) ==== + export interface SomethingTaggable { + (t: TemplateStringsArray, ...args: T[]): SomethingNewable; + } + + export interface SomethingNewable { + new (...args: T[]): any; + } + + declare const tag: SomethingTaggable; + + const a = new tag `${100} ${200}`("hello", "world"); + + const b = new tag `${"hello"} ${"world"}`(100, 200); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2350: Only a void function can be called with the 'new' keyword. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. + ~~~ +!!! error TS1005: '(' expected. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. + ~ +!!! error TS1005: ')' expected. + + const c = new tag `${100} ${200}`("hello", "world"); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2350: Only a void function can be called with the 'new' keyword. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. + ~~~ +!!! error TS1005: '(' expected. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. + ~ +!!! error TS1005: ')' expected. + + const d = new tag `${"hello"} ${"world"}`(100, 200); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2350: Only a void function can be called with the 'new' keyword. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. + ~~~ +!!! error TS1005: '(' expected. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. + ~ +!!! error TS1005: ')' expected. + \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js new file mode 100644 index 00000000000..3d2012eb0ac --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js @@ -0,0 +1,25 @@ +//// [taggedTemplatesWithTypeArguments2.ts] +export interface SomethingTaggable { + (t: TemplateStringsArray, ...args: T[]): SomethingNewable; +} + +export interface SomethingNewable { + new (...args: T[]): any; +} + +declare const tag: SomethingTaggable; + +const a = new tag `${100} ${200}`("hello", "world"); + +const b = new tag `${"hello"} ${"world"}`(100, 200); + +const c = new tag `${100} ${200}`("hello", "world"); + +const d = new tag `${"hello"} ${"world"}`(100, 200); + + +//// [taggedTemplatesWithTypeArguments2.js] +const a = new tag `${100} ${200}`("hello", "world"); +const b = new tag(`${"hello"} ${"world"}`(100, 200)); +const c = new tag(`${100} ${200}`("hello", "world")); +const d = new tag(`${"hello"} ${"world"}`(100, 200)); diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols new file mode 100644 index 00000000000..720b03dd325 --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols @@ -0,0 +1,42 @@ +=== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts === +export interface SomethingTaggable { +>SomethingTaggable : Symbol(SomethingTaggable, Decl(taggedTemplatesWithTypeArguments2.ts, 0, 0)) + + (t: TemplateStringsArray, ...args: T[]): SomethingNewable; +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments2.ts, 1, 5)) +>t : Symbol(t, Decl(taggedTemplatesWithTypeArguments2.ts, 1, 8)) +>TemplateStringsArray : Symbol(TemplateStringsArray, Decl(lib.es5.d.ts, --, --)) +>args : Symbol(args, Decl(taggedTemplatesWithTypeArguments2.ts, 1, 32)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments2.ts, 1, 5)) +>SomethingNewable : Symbol(SomethingNewable, Decl(taggedTemplatesWithTypeArguments2.ts, 2, 1)) +} + +export interface SomethingNewable { +>SomethingNewable : Symbol(SomethingNewable, Decl(taggedTemplatesWithTypeArguments2.ts, 2, 1)) + + new (...args: T[]): any; +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments2.ts, 5, 9)) +>args : Symbol(args, Decl(taggedTemplatesWithTypeArguments2.ts, 5, 12)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments2.ts, 5, 9)) +} + +declare const tag: SomethingTaggable; +>tag : Symbol(tag, Decl(taggedTemplatesWithTypeArguments2.ts, 8, 13)) +>SomethingTaggable : Symbol(SomethingTaggable, Decl(taggedTemplatesWithTypeArguments2.ts, 0, 0)) + +const a = new tag `${100} ${200}`("hello", "world"); +>a : Symbol(a, Decl(taggedTemplatesWithTypeArguments2.ts, 10, 5)) +>tag : Symbol(tag, Decl(taggedTemplatesWithTypeArguments2.ts, 8, 13)) + +const b = new tag `${"hello"} ${"world"}`(100, 200); +>b : Symbol(b, Decl(taggedTemplatesWithTypeArguments2.ts, 12, 5)) +>tag : Symbol(tag, Decl(taggedTemplatesWithTypeArguments2.ts, 8, 13)) + +const c = new tag `${100} ${200}`("hello", "world"); +>c : Symbol(c, Decl(taggedTemplatesWithTypeArguments2.ts, 14, 5)) +>tag : Symbol(tag, Decl(taggedTemplatesWithTypeArguments2.ts, 8, 13)) + +const d = new tag `${"hello"} ${"world"}`(100, 200); +>d : Symbol(d, Decl(taggedTemplatesWithTypeArguments2.ts, 16, 5)) +>tag : Symbol(tag, Decl(taggedTemplatesWithTypeArguments2.ts, 8, 13)) + diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types new file mode 100644 index 00000000000..bc05e62fcdc --- /dev/null +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types @@ -0,0 +1,70 @@ +=== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts === +export interface SomethingTaggable { +>SomethingTaggable : SomethingTaggable + + (t: TemplateStringsArray, ...args: T[]): SomethingNewable; +>T : T +>t : TemplateStringsArray +>TemplateStringsArray : TemplateStringsArray +>args : T[] +>T : T +>SomethingNewable : SomethingNewable +} + +export interface SomethingNewable { +>SomethingNewable : SomethingNewable + + new (...args: T[]): any; +>T : T +>args : T[] +>T : T +} + +declare const tag: SomethingTaggable; +>tag : SomethingTaggable +>SomethingTaggable : SomethingTaggable + +const a = new tag `${100} ${200}`("hello", "world"); +>a : any +>new tag `${100} ${200}`("hello", "world") : any +>tag `${100} ${200}` : SomethingNewable +>tag : SomethingTaggable +>`${100} ${200}` : string +>100 : 100 +>200 : 200 +>"hello" : "hello" +>"world" : "world" + +const b = new tag `${"hello"} ${"world"}`(100, 200); +>b : any +>new tag `${"hello"} ${"world"}`(100, 200) : any +>tag : SomethingTaggable +>`${"hello"} ${"world"}`(100, 200) : any +>`${"hello"} ${"world"}` : string +>"hello" : "hello" +>"world" : "world" +>100 : 100 +>200 : 200 + +const c = new tag `${100} ${200}`("hello", "world"); +>c : any +>new tag `${100} ${200}`("hello", "world") : any +>tag : SomethingTaggable +>`${100} ${200}`("hello", "world") : any +>`${100} ${200}` : string +>100 : 100 +>200 : 200 +>"hello" : "hello" +>"world" : "world" + +const d = new tag `${"hello"} ${"world"}`(100, 200); +>d : any +>new tag `${"hello"} ${"world"}`(100, 200) : any +>tag : SomethingTaggable +>`${"hello"} ${"world"}`(100, 200) : any +>`${"hello"} ${"world"}` : string +>"hello" : "hello" +>"world" : "world" +>100 : 100 +>200 : 200 + From eb8eeafc224758690e8e7fefec94ac0bde60efe9 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sun, 15 Apr 2018 16:04:25 -0700 Subject: [PATCH 054/229] Allow parsing tagged templates with type arguments in new expressions. --- src/compiler/parser.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 29d57c846f5..f5dd8fa764d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4684,9 +4684,23 @@ namespace ts { return finishNode(node); } + let expression: MemberExpression = parsePrimaryExpression(); + let typeArguments; + while (true) { + expression = parseMemberExpressionRest(expression); + typeArguments = tryParse(parseTypeArgumentsInExpression); + if (isTemplateStartOfTaggedTemplate()) { + Debug.assert(!!typeArguments, + "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'"); + expression = parseTaggedTemplateRest(expression, typeArguments); + typeArguments = undefined; + } + break; + } + const node = createNode(SyntaxKind.NewExpression, fullStart); - node.expression = parseMemberExpressionOrHigher(); - node.typeArguments = tryParse(parseTypeArgumentsInExpression); + node.expression = expression; + node.typeArguments = typeArguments; if (node.typeArguments || token() === SyntaxKind.OpenParenToken) { node.arguments = parseArgumentList(); } From a2073f121758a8c8478ebea80e99a52d0f124ca4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sun, 15 Apr 2018 16:04:47 -0700 Subject: [PATCH 055/229] Accepted baselines. --- ...ggedTemplatesWithTypeArguments2.errors.txt | 54 ++++--------------- .../taggedTemplatesWithTypeArguments2.js | 6 +-- .../taggedTemplatesWithTypeArguments2.types | 8 +-- 3 files changed, 17 insertions(+), 51 deletions(-) diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt index 958fb6715d1..51b8bd34e0c 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt @@ -1,21 +1,9 @@ -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,11): error TS2350: Only a void function can be called with the 'new' keyword. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,27): error TS1005: '(' expected. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,27): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,60): error TS1005: ')' expected. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,11): error TS2350: Only a void function can be called with the 'new' keyword. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,27): error TS1005: '(' expected. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,27): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,68): error TS1005: ')' expected. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,11): error TS2350: Only a void function can be called with the 'new' keyword. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,11): error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,27): error TS1005: '(' expected. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,27): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,68): error TS1005: ')' expected. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,30): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,11): error TS2347: Untyped function calls may not accept type arguments. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,30): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. -==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (15 errors) ==== +==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (3 errors) ==== export interface SomethingTaggable { (t: TemplateStringsArray, ...args: T[]): SomethingNewable; } @@ -29,38 +17,14 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,68 const a = new tag `${100} ${200}`("hello", "world"); const b = new tag `${"hello"} ${"world"}`(100, 200); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2350: Only a void function can be called with the 'new' keyword. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. - ~~~ -!!! error TS1005: '(' expected. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. - ~ -!!! error TS1005: ')' expected. + ~~~~~~~ +!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. const c = new tag `${100} ${200}`("hello", "world"); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2350: Only a void function can be called with the 'new' keyword. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. - ~~~ -!!! error TS1005: '(' expected. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. - ~ -!!! error TS1005: ')' expected. +!!! error TS2347: Untyped function calls may not accept type arguments. const d = new tag `${"hello"} ${"world"}`(100, 200); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2350: Only a void function can be called with the 'new' keyword. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7009: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type. - ~~~ -!!! error TS1005: '(' expected. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures. - ~ -!!! error TS1005: ')' expected. + ~~~~~~~ +!!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js index 3d2012eb0ac..33e9fef3d7f 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js @@ -20,6 +20,6 @@ const d = new tag `${"hello"} ${"world"}`(100, 200); //// [taggedTemplatesWithTypeArguments2.js] const a = new tag `${100} ${200}`("hello", "world"); -const b = new tag(`${"hello"} ${"world"}`(100, 200)); -const c = new tag(`${100} ${200}`("hello", "world")); -const d = new tag(`${"hello"} ${"world"}`(100, 200)); +const b = new tag `${"hello"} ${"world"}`(100, 200); +const c = (new tag `${100} ${200}`)("hello", "world"); +const d = (new tag `${"hello"} ${"world"}`)(100, 200); diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types index bc05e62fcdc..cd4ff1c6e13 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types @@ -38,8 +38,8 @@ const a = new tag `${100} ${200}`("hello", "world"); const b = new tag `${"hello"} ${"world"}`(100, 200); >b : any >new tag `${"hello"} ${"world"}`(100, 200) : any +>tag `${"hello"} ${"world"}` : any >tag : SomethingTaggable ->`${"hello"} ${"world"}`(100, 200) : any >`${"hello"} ${"world"}` : string >"hello" : "hello" >"world" : "world" @@ -49,8 +49,9 @@ const b = new tag `${"hello"} ${"world"}`(100, 200); const c = new tag `${100} ${200}`("hello", "world"); >c : any >new tag `${100} ${200}`("hello", "world") : any +>new tag `${100} ${200}` : any +>tag `${100} ${200}` : SomethingNewable >tag : SomethingTaggable ->`${100} ${200}`("hello", "world") : any >`${100} ${200}` : string >100 : 100 >200 : 200 @@ -60,8 +61,9 @@ const c = new tag `${100} ${200}`("hello", "world"); const d = new tag `${"hello"} ${"world"}`(100, 200); >d : any >new tag `${"hello"} ${"world"}`(100, 200) : any +>new tag `${"hello"} ${"world"}` : any +>tag `${"hello"} ${"world"}` : any >tag : SomethingTaggable ->`${"hello"} ${"world"}`(100, 200) : any >`${"hello"} ${"world"}` : string >"hello" : "hello" >"world" : "world" From 8cb515ab1324f3dae7e011ce78a0028b39a56390 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 16 Apr 2018 07:16:26 -0700 Subject: [PATCH 056/229] Add members for numeric and symbol named properties in mapped types --- src/compiler/checker.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 18f9812844c..ff2ba12783a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6035,7 +6035,7 @@ namespace ts { (constraintDeclaration).operator === SyntaxKind.KeyOfKeyword) { // We have a { [P in keyof T]: X } for (const prop of getPropertiesOfType(modifiersType)) { - addMemberForKeyType(getLiteralTypeFromPropertyName(prop, include), undefined, prop); + addMemberForKeyType(getLiteralTypeFromPropertyName(prop, include), /*_index*/ undefined, prop); } if (modifiersType.flags & TypeFlags.Any || getIndexInfoOfType(modifiersType, IndexKind.String)) { addMemberForKeyType(stringType); @@ -6062,7 +6062,7 @@ namespace ts { const propType = instantiateType(templateType, templateMapper); // If the current iteration type constituent is a string literal type, create a property. // Otherwise, for type string create a string index signature. - if (t.flags & TypeFlags.StringLiteral) { + if (t.flags & TypeFlags.StringOrNumberLiteralOrUnique) { const propName = getLateBoundNameFromType(t as LiteralType); const modifiersProp = getPropertyOfType(modifiersType, propName); const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional || @@ -6511,7 +6511,7 @@ namespace ts { let declarations: Declaration[]; let commonType: Type; let nameType: Type; - let propTypes: Type[] = []; + const propTypes: Type[] = []; let first = true; for (const prop of props) { declarations = addRange(declarations, prop.declarations); @@ -8146,7 +8146,7 @@ namespace ts { type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? keyofConstraintType : keyofStringsOnly ? getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : - getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol); + getLiteralTypeFromPropertyNames(type, TypeFlags.StringOrNumberLiteralOrUnique); } function getExtractStringType(type: Type) { From a297a28fd5a18c37427d743305f33e0a2f2fdcbb Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 16 Apr 2018 08:27:25 -0700 Subject: [PATCH 057/229] Use getPossibleSymbolReferenceNodes in one more place (#23378) --- src/services/findAllReferences.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 5b4689cc476..7c5922035ea 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -704,9 +704,8 @@ namespace ts.FindAllReferences.Core { export function isSymbolReferencedInFile(definition: Identifier, checker: TypeChecker, sourceFile: SourceFile) { const symbol = checker.getSymbolAtLocation(definition); if (!symbol) return true; // Be lenient with invalid code. - return getPossibleSymbolReferencePositions(sourceFile, symbol.name).some(position => { - const token = tryCast(getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true), isIdentifier); - if (!token || token === definition || token.escapedText !== definition.escapedText) return false; + return getPossibleSymbolReferenceNodes(sourceFile, symbol.name).some(token => { + if (!isIdentifier(token) || token === definition || token.escapedText !== definition.escapedText) return false; const referenceSymbol = checker.getSymbolAtLocation(token); return referenceSymbol === symbol || checker.getShorthandAssignmentValueSymbol(token.parent) === symbol From f5b7826c1f0548b5ae79413a5458db9c19b6440b Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 16 Apr 2018 16:10:41 +0000 Subject: [PATCH 058/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 1e9d7342817..efac12c6e66 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3900,6 +3900,9 @@ + + + @@ -6015,6 +6018,9 @@ + + + From cc6bc763bcf7153acbed9df46e0f4ff011e5914b Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 16 Apr 2018 09:30:10 -0700 Subject: [PATCH 059/229] Simplify getConvertibleFieldAtPosition (#23315) --- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 9 ++- .../generateGetAccessorAndSetAccessor.ts | 55 +++---------------- .../reference/api/tsserverlibrary.d.ts | 7 ++- tests/baselines/reference/api/typescript.d.ts | 7 ++- 5 files changed, 27 insertions(+), 52 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 987d403e7cd..63720d55900 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -879,6 +879,7 @@ namespace ts { export interface PropertyDeclaration extends ClassElement, JSDocContainer { kind: SyntaxKind.PropertyDeclaration; + parent: ClassLikeDeclaration; name: PropertyName; questionToken?: QuestionToken; // Present for use with reporting a grammar error exclamationToken?: ExclamationToken; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 61c24ee12ec..f975e27dca3 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3037,6 +3037,10 @@ namespace ts { return (node as HasType).type || (isInJavaScriptFile(node) ? getJSDocType(node) : undefined); } + export function getTypeAnnotationNode(node: Node): TypeNode | undefined { + return (node as HasType).type; + } + /** * Gets the effective return type annotation of a signature. If the node was parsed in a * JavaScript file, gets the return type annotation from JSDoc. @@ -4271,8 +4275,9 @@ namespace ts { } } - export function isParameterPropertyDeclaration(node: Node): node is ParameterDeclaration { - return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && node.parent.kind === SyntaxKind.Constructor && isClassLike(node.parent.parent); + export type ParameterPropertyDeclaration = ParameterDeclaration & { parent: ConstructorDeclaration, name: Identifier }; + export function isParameterPropertyDeclaration(node: Node): node is ParameterPropertyDeclaration { + return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && node.parent.kind === SyntaxKind.Constructor; } export function isEmptyBindingPattern(node: BindingName): node is BindingPattern { diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 2f1f5279680..33ecbbaab66 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -4,17 +4,14 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const actionDescription = Diagnostics.Generate_get_and_set_accessors.message; registerRefactor(actionName, { getEditsForAction, getAvailableActions }); - type AcceptedDeclaration = ParameterDeclaration | PropertyDeclaration | PropertyAssignment; + type AcceptedDeclaration = ParameterPropertyDeclaration | PropertyDeclaration | PropertyAssignment; type AcceptedNameType = Identifier | StringLiteral; type ContainerDeclaration = ClassLikeDeclaration | ObjectLiteralExpression; - interface DeclarationInfo { + interface Info { container: ContainerDeclaration; isStatic: boolean; type: TypeNode | undefined; - } - - interface Info extends DeclarationInfo { declaration: AcceptedDeclaration; fieldName: AcceptedNameType; accessorName: AcceptedNameType; @@ -92,46 +89,6 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { return modifiers && createNodeArray(modifiers); } - function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): DeclarationInfo | undefined { - if (!isClassLike(propertyDeclaration.parent) || !propertyDeclaration.parent.members) return undefined; - - return { - isStatic: hasStaticModifier(propertyDeclaration), - type: propertyDeclaration.type, - container: propertyDeclaration.parent - }; - } - - function getParameterPropertyDeclarationInfo(parameterDeclaration: ParameterDeclaration): DeclarationInfo | undefined { - if (!isClassLike(parameterDeclaration.parent.parent) || !parameterDeclaration.parent.parent.members) return undefined; - - return { - isStatic: false, - type: parameterDeclaration.type, - container: parameterDeclaration.parent.parent - }; - } - - function getPropertyAssignmentDeclarationInfo(propertyAssignment: PropertyAssignment): DeclarationInfo | undefined { - return { - isStatic: false, - type: undefined, - container: propertyAssignment.parent - }; - } - - function getDeclarationInfo(declaration: AcceptedDeclaration) { - if (isPropertyDeclaration(declaration)) { - return getPropertyDeclarationInfo(declaration); - } - else if (isPropertyAssignment(declaration)) { - return getPropertyAssignmentDeclarationInfo(declaration); - } - else { - return getParameterPropertyDeclarationInfo(declaration); - } - } - function getConvertibleFieldAtPosition(file: SourceFile, startPosition: number): Info | undefined { const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); const declaration = findAncestor(node.parent, isAcceptedDeclaration); @@ -139,15 +96,17 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static; if (!declaration || !isConvertableName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined; - const info = getDeclarationInfo(declaration); const fieldName = createPropertyName(getUniqueName(`_${declaration.name.text}`, file.text), declaration.name); + const accessorName = createPropertyName(declaration.name.text, declaration.name); suppressLeadingAndTrailingTrivia(fieldName); suppressLeadingAndTrailingTrivia(declaration); return { - ...info, + isStatic: hasStaticModifier(declaration), + type: getTypeAnnotationNode(declaration), + container: declaration.kind === SyntaxKind.Parameter ? declaration.parent.parent : declaration.parent, declaration, fieldName, - accessorName: createPropertyName(declaration.name.text, declaration.name) + accessorName, }; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 2e8e3f3871d..04fabe6ff09 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -585,6 +585,7 @@ declare namespace ts { } interface PropertyDeclaration extends ClassElement, JSDocContainer { kind: SyntaxKind.PropertyDeclaration; + parent: ClassLikeDeclaration; name: PropertyName; questionToken?: QuestionToken; exclamationToken?: ExclamationToken; @@ -3010,7 +3011,11 @@ declare namespace ts { */ function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; - function isParameterPropertyDeclaration(node: Node): node is ParameterDeclaration; + type ParameterPropertyDeclaration = ParameterDeclaration & { + parent: ConstructorDeclaration; + name: Identifier; + }; + function isParameterPropertyDeclaration(node: Node): node is ParameterPropertyDeclaration; function isEmptyBindingPattern(node: BindingName): node is BindingPattern; function isEmptyBindingElement(node: BindingElement): boolean; function getCombinedModifierFlags(node: Node): ModifierFlags; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 378949d5b5b..506aa6b15c6 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -585,6 +585,7 @@ declare namespace ts { } interface PropertyDeclaration extends ClassElement, JSDocContainer { kind: SyntaxKind.PropertyDeclaration; + parent: ClassLikeDeclaration; name: PropertyName; questionToken?: QuestionToken; exclamationToken?: ExclamationToken; @@ -3010,7 +3011,11 @@ declare namespace ts { */ function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; - function isParameterPropertyDeclaration(node: Node): node is ParameterDeclaration; + type ParameterPropertyDeclaration = ParameterDeclaration & { + parent: ConstructorDeclaration; + name: Identifier; + }; + function isParameterPropertyDeclaration(node: Node): node is ParameterPropertyDeclaration; function isEmptyBindingPattern(node: BindingName): node is BindingPattern; function isEmptyBindingElement(node: BindingElement): boolean; function getCombinedModifierFlags(node: Node): ModifierFlags; From a60caba467597f2f49283a3735160f47adc9cd13 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Mon, 16 Apr 2018 11:22:24 -0700 Subject: [PATCH 060/229] In outliningElementsCollector, treat 'else if' as having same depth as the 'if' --- src/services/outliningElementsCollector.ts | 12 ++- .../fourslash/getOutliningSpansDepthElseIf.ts | 89 +++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/getOutliningSpansDepthElseIf.ts diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 90c53d47561..9d590ffef61 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -21,7 +21,17 @@ namespace ts.OutliningElementsCollector { if (span) out.push(span); depthRemaining--; - n.forEachChild(walk); + if (isIfStatement(n) && isIfStatement(n.elseStatement)) { + // Consider an 'else if' to be on the same depth as the 'if'. + walk(n.expression); + walk(n.thenStatement); + depthRemaining++; + walk(n.elseStatement); + depthRemaining--; + } + else { + n.forEachChild(walk); + } depthRemaining++; }); } diff --git a/tests/cases/fourslash/getOutliningSpansDepthElseIf.ts b/tests/cases/fourslash/getOutliningSpansDepthElseIf.ts new file mode 100644 index 00000000000..1e349e5b190 --- /dev/null +++ b/tests/cases/fourslash/getOutliningSpansDepthElseIf.ts @@ -0,0 +1,89 @@ +/// + +// Tests that each 'else if' does not count towards a higher nesting depth. + +////if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else if (1)[| { +//// 1; +////}|] else[| { +//// 1; +////}|] + +verify.outliningSpansInCurrentFile(test.ranges()); From f0057f9a333ebeba8dd4b7ee882634be83904f44 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 16 Apr 2018 11:48:04 -0700 Subject: [PATCH 061/229] Remove condition --- src/services/preProcess.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts index 7b802301204..6c5f6c1b2ff 100644 --- a/src/services/preProcess.ts +++ b/src/services/preProcess.ts @@ -20,9 +20,7 @@ namespace ts { let externalModule = false; function nextToken() { - if (currentToken) { - lastToken = currentToken; - } + lastToken = currentToken; currentToken = scanner.scan(); if (currentToken === SyntaxKind.OpenBraceToken) { braceNesting++; From aac9ef5e513d35c34d513c22fa63510101f0953a Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 16 Apr 2018 13:16:04 -0700 Subject: [PATCH 062/229] convertToEs6Module: Avoid replacing entire function (#22507) * convertToEs6Module: Avoid replacing entire function * Code review * Fix typo --- src/services/codefixes/convertToEs6Module.ts | 53 ++++++++++++------- src/services/textChanges.ts | 43 +++++++++++++-- ...refactorConvertToEs6Module_export_alias.ts | 2 +- ...refactorConvertToEs6Module_export_named.ts | 15 ++++-- ...ToEs6Module_export_namedClassExpression.ts | 14 +++++ ...s6Module_export_namedFunctionExpression.ts | 2 +- ...torConvertToEs6Module_export_referenced.ts | 7 +-- ...vertToEs6Module_expressionToDeclaration.ts | 4 +- 8 files changed, 105 insertions(+), 35 deletions(-) create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index 67aaa60f186..8ffba3218c0 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -114,8 +114,8 @@ namespace ts.codefix { return false; } case SyntaxKind.BinaryExpression: { - const { left, operatorToken, right } = expression as BinaryExpression; - return operatorToken.kind === SyntaxKind.EqualsToken && convertAssignment(sourceFile, checker, statement as ExpressionStatement, left, right, changes, exports); + const { operatorToken } = expression as BinaryExpression; + return operatorToken.kind === SyntaxKind.EqualsToken && convertAssignment(sourceFile, checker, expression as BinaryExpression, changes, exports); } } } @@ -144,7 +144,7 @@ namespace ts.codefix { return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers); } else { - // Move it out to its own variable statement. + // Move it out to its own variable statement. (This will not be used if `!foundImport`) return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags)); } }); @@ -177,12 +177,11 @@ namespace ts.codefix { function convertAssignment( sourceFile: SourceFile, checker: TypeChecker, - statement: ExpressionStatement, - left: Expression, - right: Expression, + assignment: BinaryExpression, changes: textChanges.ChangeTracker, exports: ExportRenames, ): ModuleExportsChanged { + const { left, right } = assignment; if (!isPropertyAccessExpression(left)) { return false; } @@ -190,7 +189,7 @@ namespace ts.codefix { if (isExportsOrModuleExportsOrAlias(sourceFile, left)) { if (isExportsOrModuleExportsOrAlias(sourceFile, right)) { // `const alias = module.exports;` or `module.exports = alias;` can be removed. - changes.deleteNode(sourceFile, statement); + changes.deleteNode(sourceFile, assignment.parent); } else { let newNodes = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right) : undefined; @@ -198,12 +197,12 @@ namespace ts.codefix { if (!newNodes) { ([newNodes, changedToDefaultExport] = convertModuleExportsToExportDefault(right, checker)); } - changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes); return changedToDefaultExport; } } else if (isExportsOrModuleExportsOrAlias(sourceFile, left.expression)) { - convertNamedExport(sourceFile, statement, left.name, right, changes, exports); + convertNamedExport(sourceFile, assignment as BinaryExpression & { left: PropertyAccessExpression }, changes, exports); } return false; @@ -223,7 +222,7 @@ namespace ts.codefix { case SyntaxKind.SpreadAssignment: return undefined; case SyntaxKind.PropertyAssignment: - return !isIdentifier(prop.name) ? undefined : convertExportsDotXEquals(prop.name.text, prop.initializer); + return !isIdentifier(prop.name) ? undefined : convertExportsDotXEquals_replaceNode(prop.name.text, prop.initializer); case SyntaxKind.MethodDeclaration: return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [createToken(SyntaxKind.ExportKeyword)], prop); default: @@ -234,14 +233,12 @@ namespace ts.codefix { function convertNamedExport( sourceFile: SourceFile, - statement: Statement, - propertyName: Identifier, - right: Expression, + assignment: BinaryExpression & { left: PropertyAccessExpression }, changes: textChanges.ChangeTracker, exports: ExportRenames, ): void { // If "originalKeywordKind" was set, this is e.g. `exports. - const { text } = propertyName; + const { text } = assignment.left.name; const rename = exports.get(text); if (rename !== undefined) { /* @@ -249,13 +246,13 @@ namespace ts.codefix { export { _class as class }; */ const newNodes = [ - makeConst(/*modifiers*/ undefined, rename, right), + makeConst(/*modifiers*/ undefined, rename, assignment.right), makeExportDeclaration([createExportSpecifier(rename, text)]), ]; - changes.replaceNodeWithNodes(sourceFile, statement, newNodes); + changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes); } else { - changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right)); + convertExportsPropertyAssignment(assignment, sourceFile, changes); } } @@ -303,7 +300,27 @@ namespace ts.codefix { return makeExportDeclaration([createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier); } - function convertExportsDotXEquals(name: string | undefined, exported: Expression): Statement { + function convertExportsPropertyAssignment({ left, right, parent }: BinaryExpression & { left: PropertyAccessExpression }, sourceFile: SourceFile, changes: textChanges.ChangeTracker): void { + const name = left.name.text; + if ((isFunctionExpression(right) || isArrowFunction(right) || isClassExpression(right)) && (!right.name || right.name.text === name)) { + // `exports.f = function() {}` -> `export function f() {}` -- Replace `exports.f = ` with `export `, and insert the name after `function`. + changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, createToken(SyntaxKind.ExportKeyword), { suffix: " " }); + + if (!right.name) changes.insertName(sourceFile, right, name); + + const semi = findChildOfKind(parent, SyntaxKind.SemicolonToken, sourceFile); + if (semi) changes.deleteNode(sourceFile, semi, { useNonAdjustedEndPosition: true }); + } + else { + // `exports.f = function g() {}` -> `export const f = function g() {}` -- just replace `exports.` with `export const ` + changes.replaceNodeRangeWithNodes(sourceFile, left.expression, findChildOfKind(left, SyntaxKind.DotToken, sourceFile)!, + [createToken(SyntaxKind.ExportKeyword), createToken(SyntaxKind.ConstKeyword)], + { joiner: " ", suffix: " " }); + } + } + + // TODO: GH#22492 this will cause an error if a change has been made inside the body of the node. + function convertExportsDotXEquals_replaceNode(name: string | undefined, exported: Expression): Statement { const modifiers = [createToken(SyntaxKind.ExportKeyword)]; switch (exported.kind) { case SyntaxKind.FunctionExpression: { diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 979c44b2cd7..b54caf402b1 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -100,6 +100,10 @@ namespace ts.textChanges { preserveLeadingWhitespace?: boolean; } + export interface ReplaceWithMultipleNodesOptions extends InsertNodeOptions { + readonly joiner?: string; + } + enum ChangeKind { Remove, ReplaceWithSingleNode, @@ -130,7 +134,7 @@ namespace ts.textChanges { interface ReplaceWithMultipleNodes extends BaseChange { readonly kind: ChangeKind.ReplaceWithMultipleNodes; readonly nodes: ReadonlyArray; - readonly options?: InsertNodeOptions; + readonly options?: ReplaceWithMultipleNodesOptions; } interface ChangeText extends BaseChange { @@ -303,7 +307,7 @@ namespace ts.textChanges { this.replaceRange(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNode, options); } - private replaceRangeWithNodes(sourceFile: SourceFile, range: TextRange, newNodes: ReadonlyArray, options: InsertNodeOptions = {}) { + private replaceRangeWithNodes(sourceFile: SourceFile, range: TextRange, newNodes: ReadonlyArray, options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = {}) { this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile, range, options, nodes: newNodes }); return this; } @@ -312,7 +316,7 @@ namespace ts.textChanges { return this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNodes, options); } - public replaceNodeRangeWithNodes(sourceFile: SourceFile, startNode: Node, endNode: Node, newNodes: ReadonlyArray, options: ChangeNodeOptions = useNonAdjustedPositions) { + public replaceNodeRangeWithNodes(sourceFile: SourceFile, startNode: Node, endNode: Node, newNodes: ReadonlyArray, options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = useNonAdjustedPositions) { return this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNodes, options); } @@ -326,7 +330,7 @@ namespace ts.textChanges { this.replaceRange(sourceFile, createTextRange(pos), newNode, options); } - private insertNodesAt(sourceFile: SourceFile, pos: number, newNodes: ReadonlyArray, options: InsertNodeOptions = {}): void { + private insertNodesAt(sourceFile: SourceFile, pos: number, newNodes: ReadonlyArray, options: ReplaceWithMultipleNodesOptions = {}): void { this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile, options, nodes: newNodes, range: { pos, end: pos } }); } @@ -483,6 +487,35 @@ namespace ts.textChanges { return Debug.failBadSyntaxKind(node); // We haven't handled this kind of node yet -- add it } + public insertName(sourceFile: SourceFile, node: FunctionExpression | ClassExpression | ArrowFunction, name: string): void { + Debug.assert(!node.name); + if (node.kind === SyntaxKind.ArrowFunction) { + const arrow = findChildOfKind(node, SyntaxKind.EqualsGreaterThanToken, sourceFile)!; + const lparen = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile); + if (lparen) { + // `() => {}` --> `function f() {}` + this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [createToken(SyntaxKind.FunctionKeyword), createIdentifier(name)], { joiner: " " }); + this.deleteNode(sourceFile, arrow); + } + else { + // `x => {}` -> `function f(x) {}` + this.insertText(sourceFile, first(node.parameters).getStart(sourceFile), `function ${name}(`); + // Replacing full range of arrow to get rid of the leading space -- replace ` =>` with `)` + this.replaceRange(sourceFile, arrow, createToken(SyntaxKind.CloseParenToken)); + } + + if (node.body.kind !== SyntaxKind.Block) { + // `() => 0` => `function f() { return 0; }` + this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [createToken(SyntaxKind.OpenBraceToken), createToken(SyntaxKind.ReturnKeyword)], { joiner: " ", suffix: " " }); + this.insertNodesAt(sourceFile, node.body.end, [createToken(SyntaxKind.SemicolonToken), createToken(SyntaxKind.CloseBraceToken)], { joiner: " " }); + } + } + else { + const pos = findChildOfKind(node, node.kind === SyntaxKind.FunctionExpression ? SyntaxKind.FunctionKeyword : SyntaxKind.ClassKeyword, sourceFile)!.end; + this.insertNodeAt(sourceFile, pos, createIdentifier(name), { prefix: " " }); + } + } + /** * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range, * i.e. arguments in arguments lists, parameters in parameter lists etc. @@ -652,7 +685,7 @@ namespace ts.textChanges { const { options = {}, range: { pos } } = change; const format = (n: Node) => getFormattedTextOfNode(n, sourceFile, pos, options, newLineCharacter, formatContext, validate); const text = change.kind === ChangeKind.ReplaceWithMultipleNodes - ? change.nodes.map(n => removeSuffix(format(n), newLineCharacter)).join(newLineCharacter) + ? change.nodes.map(n => removeSuffix(format(n), newLineCharacter)).join(change.options.joiner || newLineCharacter) : format(change.node); // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line const noIndent = (options.preserveLeadingWhitespace || options.indentation !== undefined || getLineStartPositionForPosition(pos, sourceFile) === pos) ? text : text.replace(/^\s+/, ""); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts index 73cd606adf9..8749488b88e 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts @@ -10,6 +10,6 @@ verify.codeFix({ description: "Convert to ES6 module", newFileContent: ` -export function f() { } +export function f() {} `, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts index 6f4c3ecbde4..60d2436ddb0 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts @@ -6,6 +6,10 @@ ////[|exports.f = function() {}|]; ////exports.C = class {}; ////exports.x = 0; +////exports.a1 = () => {}; +////exports.a2 = () => 0; +////exports.a3 = x => { x; }; +////exports.a4 = x => x; verify.getSuggestionDiagnostics([{ message: "File is a CommonJS module; it may be converted to an ES6 module.", @@ -15,8 +19,11 @@ verify.getSuggestionDiagnostics([{ verify.codeFix({ description: "Convert to ES6 module", newFileContent: -`export function f() { } -export class C { -} -export const x = 0;`, +`export function f() {} +export class C {} +export const x = 0; +export function a1() {} +export function a2() { return 0; } +export function a3(x) { x; } +export function a4(x) { return x; }`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts new file mode 100644 index 00000000000..ff14f00867d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////exports.C = class E { static instance = new E(); } +////exports.D = class D { static instance = new D(); } + +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`export const C = class E { static instance = new E(); } +export class D { static instance = new D(); }`, +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts index dbd4e6a0a4c..94a14d1a4c3 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts @@ -9,6 +9,6 @@ verify.codeFix({ description: "Convert to ES6 module", newFileContent: -`export const f = function g() { g(); }; +`export const f = function g() { g(); } export function h() { h(); }`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts index e4b4c34f86a..0811ea13e99 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts @@ -12,7 +12,7 @@ //// ////exports.z = 2; ////exports.f = function(z) { -//// z; +//// exports.z; z; ////} // TODO: GH#22492 Should be a able access `exports.z` inside `exports.f` @@ -28,8 +28,9 @@ const _y = y; export { _y as y }; _y; -export const z = 2; +const _z = 2; +export { _z as z }; export function f(z) { - z; + _z; z; }`, }); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts index 0525a2b881c..e22aa176738 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts @@ -10,7 +10,5 @@ verify.codeFix({ description: "Convert to ES6 module", newFileContent: `export async function* f(p) { p; } -export class C extends D { - m() { } -}`, +export class C extends D { m() {} }`, }); From 5ce6b6a2aea67c36f5a0820dd3cc24b2859b0865 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 16 Apr 2018 13:53:30 -0700 Subject: [PATCH 063/229] Convert gulp processDiagnostics builder to project compilation --- Gulpfile.ts | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 1c6cfdd7ed1..26622f36fe8 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -362,20 +362,11 @@ const builtGeneratedDiagnosticMessagesJSON = path.join(builtLocalDirectory, "dia // processDiagnosticMessages script gulp.task(processDiagnosticMessagesJs, /*help*/ false, [], () => { - const settings: tsc.Settings = getCompilerSettings({ - target: "es5", - declaration: false, - removeComments: true, - noResolve: false, - stripInternal: false, - outFile: processDiagnosticMessagesJs - }, /*useBuiltCompiler*/ false); - return gulp.src(processDiagnosticMessagesTs) + const diagsProject = tsc.createProject('./scripts/processDiagnosticMessages.tsconfig.json'); + return diagsProject.src() .pipe(newer(processDiagnosticMessagesJs)) - .pipe(sourcemaps.init()) - .pipe(tsc(settings)) - .pipe(sourcemaps.write(".")) - .pipe(gulp.dest(".")); + .pipe(diagsProject()) + .pipe(gulp.dest(scriptsDirectory)); }); // The generated diagnostics map; built for the compiler and for the "generate-diagnostics" task From 1bafc49da07a970e728f2b553d68b8d41bb2f9c7 Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 16 Apr 2018 22:11:09 +0000 Subject: [PATCH 064/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ 4 files changed, 48 insertions(+) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index db17f37967b..0ef1aeed0cc 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3906,6 +3906,15 @@ + + + + + + + + + @@ -6018,6 +6027,9 @@ + + + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 342918edc19..259d4b3b90e 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3906,6 +3906,15 @@ + + + + + + + + + @@ -6018,6 +6027,9 @@ + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index a0f54926f3f..43d2f167e96 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3897,6 +3897,15 @@ + + + + + + + + + @@ -6009,6 +6018,9 @@ + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index b341aa7ea84..07d26979bf8 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3896,6 +3896,15 @@ + + + + + + + + + @@ -6008,6 +6017,9 @@ + + + From cae464058a5a36fb1de4988bd6e649260ef6ee74 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 16 Apr 2018 15:29:02 -0700 Subject: [PATCH 065/229] Delete "delete me" files (#23446) --- src/harness/tsconfig.json | 2 -- src/server/tsconfig.json | 2 -- src/server/tsconfig.library.json | 2 -- src/services/codefixes/fixes.ts | 1 - src/services/refactors/refactors.ts | 1 - src/services/tsconfig.json | 2 -- 6 files changed, 10 deletions(-) delete mode 100644 src/services/codefixes/fixes.ts delete mode 100644 src/services/refactors/refactors.ts diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 0d56447b28a..3ad653403cf 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -112,10 +112,8 @@ "../services/codefixes/fixInvalidImportSyntax.ts", "../services/codefixes/fixStrictClassInitialization.ts", "../services/codefixes/useDefaultImport.ts", - "../services/codefixes/fixes.ts", "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", - "../services/refactors/refactors.ts", "../services/sourcemaps.ts", "../services/services.ts", "../services/breakpoints.ts", diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index fe19cd418bd..dc732604ab6 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -108,10 +108,8 @@ "../services/codefixes/fixInvalidImportSyntax.ts", "../services/codefixes/fixStrictClassInitialization.ts", "../services/codefixes/useDefaultImport.ts", - "../services/codefixes/fixes.ts", "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", - "../services/refactors/refactors.ts", "../services/sourcemaps.ts", "../services/services.ts", "../services/breakpoints.ts", diff --git a/src/server/tsconfig.library.json b/src/server/tsconfig.library.json index 54353daf5c6..dd0196fab76 100644 --- a/src/server/tsconfig.library.json +++ b/src/server/tsconfig.library.json @@ -114,10 +114,8 @@ "../services/codefixes/fixInvalidImportSyntax.ts", "../services/codefixes/fixStrictClassInitialization.ts", "../services/codefixes/useDefaultImport.ts", - "../services/codefixes/fixes.ts", "../services/refactors/extractSymbol.ts", "../services/refactors/generateGetAccessorAndSetAccessor.ts", - "../services/refactors/refactors.ts", "../services/sourcemaps.ts", "../services/services.ts", "../services/breakpoints.ts", diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts deleted file mode 100644 index bc845bd8dc0..00000000000 --- a/src/services/codefixes/fixes.ts +++ /dev/null @@ -1 +0,0 @@ -// Please delete me later. diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts deleted file mode 100644 index bc845bd8dc0..00000000000 --- a/src/services/refactors/refactors.ts +++ /dev/null @@ -1 +0,0 @@ -// Please delete me later. diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index a54790df3be..31b35a44271 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -105,10 +105,8 @@ "codefixes/fixInvalidImportSyntax.ts", "codefixes/fixStrictClassInitialization.ts", "codefixes/useDefaultImport.ts", - "codefixes/fixes.ts", "refactors/extractSymbol.ts", "refactors/generateGetAccessorAndSetAccessor.ts", - "refactors/refactors.ts", "sourcemaps.ts", "services.ts", "breakpoints.ts", From 676983cb3e274870eff0d86d3f0f70121b4fcb4f Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 16 Apr 2018 13:26:21 -0700 Subject: [PATCH 066/229] Normalize paths to search for highlights --- src/server/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/session.ts b/src/server/session.ts index 1076d17e11f..ef2c9f92a83 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -793,7 +793,7 @@ namespace ts.server { private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); - const documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, args.filesToSearch); + const documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, map(args.filesToSearch, toNormalizedPath)); if (!documentHighlights) { return emptyArray; From 003c0a6743e1a0c41d7410b91c9cd6902a3f9397 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 16 Apr 2018 15:58:25 -0700 Subject: [PATCH 067/229] Move normalization into services --- src/server/session.ts | 2 +- src/services/services.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/session.ts b/src/server/session.ts index ef2c9f92a83..1076d17e11f 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -793,7 +793,7 @@ namespace ts.server { private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); - const documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, map(args.filesToSearch, toNormalizedPath)); + const documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, args.filesToSearch); if (!documentHighlights) { return emptyArray; diff --git a/src/services/services.ts b/src/services/services.ts index bed301e452f..ab359c35323 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1673,6 +1673,7 @@ namespace ts { } function getDocumentHighlights(fileName: string, position: number, filesToSearch: ReadonlyArray): DocumentHighlights[] { + filesToSearch = ts.map(filesToSearch, ts.normalizePath); Debug.assert(contains(filesToSearch, fileName)); synchronizeHostData(); const sourceFilesToSearch = map(filesToSearch, f => Debug.assertDefined(program.getSourceFile(f))); From e9d6f788ca64202a3fcefeb4b1aeee4b119ac1f2 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 16 Apr 2018 15:58:39 -0700 Subject: [PATCH 068/229] Add test --- src/harness/fourslash.ts | 7 ++++++- src/harness/virtualFileSystem.ts | 2 +- tests/cases/fourslash/documentHighlights_windowsPath.ts | 7 +++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/documentHighlights_windowsPath.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index b479b5596a8..f85f4b443de 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2910,6 +2910,11 @@ Actual: ${stringify(fullActual)}`); } private verifyDocumentHighlights(expectedRanges: Range[], fileNames: ReadonlyArray = [this.activeFile.fileName]) { + expectedRanges = ts.map(expectedRanges, r => { + r.fileName = ts.normalizePath(r.fileName); + return r; + }); + fileNames = ts.map(fileNames, ts.normalizePath); const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNames) || []; for (const dh of documentHighlights) { @@ -3219,7 +3224,7 @@ Actual: ${stringify(fullActual)}`); } } else if (ts.isString(indexOrName)) { - let name = indexOrName; + let name = ts.normalizePath(indexOrName); // names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName name = name.indexOf("/") === -1 ? (this.basePath + "/" + name) : name; diff --git a/src/harness/virtualFileSystem.ts b/src/harness/virtualFileSystem.ts index 16267a092fc..698f99616ca 100644 --- a/src/harness/virtualFileSystem.ts +++ b/src/harness/virtualFileSystem.ts @@ -125,7 +125,7 @@ namespace Utils { addFile(path: string, content?: Harness.LanguageService.ScriptInfo) { const absolutePath = ts.normalizePath(ts.getNormalizedAbsolutePath(path, this.currentDirectory)); - const fileName = ts.getBaseFileName(path); + const fileName = ts.getBaseFileName(absolutePath); const directoryPath = ts.getDirectoryPath(absolutePath); const directory = this.addDirectory(directoryPath); return directory ? directory.addFile(fileName, content) : undefined; diff --git a/tests/cases/fourslash/documentHighlights_windowsPath.ts b/tests/cases/fourslash/documentHighlights_windowsPath.ts new file mode 100644 index 00000000000..594f175745b --- /dev/null +++ b/tests/cases/fourslash/documentHighlights_windowsPath.ts @@ -0,0 +1,7 @@ +/// + +//@Filename: C:\a\b\c.ts +////var /*1*/[|x|] = 1; + +const range = test.ranges()[0]; +verify.documentHighlightsOf(range, [range], { filesToSearch: [range.fileName] }); \ No newline at end of file From 606492b6773b96a11e92d8fa7b3f41322d3638ea Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Mon, 16 Apr 2018 16:20:12 -0700 Subject: [PATCH 069/229] Fix lint error and normalization issue --- src/harness/fourslash.ts | 2 +- src/services/services.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f85f4b443de..d2b389c4373 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3231,7 +3231,7 @@ Actual: ${stringify(fullActual)}`); const availableNames: string[] = []; const result = ts.forEach(this.testData.files, file => { - const fn = file.fileName; + const fn = ts.normalizePath(file.fileName); if (fn) { if (fn === name) { return file; diff --git a/src/services/services.ts b/src/services/services.ts index ab359c35323..bceb7f572af 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1673,7 +1673,7 @@ namespace ts { } function getDocumentHighlights(fileName: string, position: number, filesToSearch: ReadonlyArray): DocumentHighlights[] { - filesToSearch = ts.map(filesToSearch, ts.normalizePath); + filesToSearch = map(filesToSearch, normalizePath); Debug.assert(contains(filesToSearch, fileName)); synchronizeHostData(); const sourceFilesToSearch = map(filesToSearch, f => Debug.assertDefined(program.getSourceFile(f))); From 40fd6aebdcac8ecf730517bd5005591eef2f4bff Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 16 Apr 2018 16:46:27 -0700 Subject: [PATCH 070/229] Shrink span for convert-to-es6-module suggestion (#23441) --- src/services/suggestionDiagnostics.ts | 6 +++++- .../fourslash/refactorConvertToEs6Module_export_named.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 1fc1d671e43..d9f55a78d82 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -6,7 +6,7 @@ namespace ts { const diags: Diagnostic[] = []; if (sourceFile.commonJsModuleIndicator) { - diags.push(createDiagnosticForNode(sourceFile.commonJsModuleIndicator, Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module)); + diags.push(createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module)); } const isJsFile = isSourceFileJavaScript(sourceFile); @@ -61,4 +61,8 @@ namespace ts { return undefined; } } + + function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator: Node): Node { + return isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator; + } } diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts index 60d2436ddb0..a748b9844a6 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts @@ -3,7 +3,7 @@ // @allowJs: true // @Filename: /a.js -////[|exports.f = function() {}|]; +////[|exports.f|] = function() {}; ////exports.C = class {}; ////exports.x = 0; ////exports.a1 = () => {}; From 1e6e679a539c475dd7a7caa1b0f13dbf873f3a00 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 17 Apr 2018 04:10:48 +0000 Subject: [PATCH 071/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 52881bd0f4e..d3663b384db 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3906,6 +3906,15 @@ + + + + + + + + + @@ -6018,6 +6027,9 @@ + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 4b42ff8b2bf..0e70ff04cca 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3897,6 +3897,15 @@ + + + + + + + + + @@ -6009,6 +6018,9 @@ + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 1ac1d8a83e6..72116417c1b 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3890,6 +3890,15 @@ + + + + + + + + + @@ -6002,6 +6011,9 @@ + + + From 9dff614bd2fb6ec41ed3b1603a2879b761e0f4b4 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 17 Apr 2018 01:47:43 -0700 Subject: [PATCH 072/229] Combined the "Found X error(s)" and "Compilation" complete --watch messages --- src/compiler/diagnosticMessages.json | 8 ++------ src/compiler/watch.ts | 11 +++++------ src/harness/unittests/tscWatchMode.ts | 10 ++++------ 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c665744b1ea..235788258af 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2943,10 +2943,6 @@ "category": "Message", "code": 6040 }, - "Compilation complete. Watching for file changes.": { - "category": "Message", - "code": 6042 - }, "Generates corresponding '.map' file.": { "category": "Message", "code": 6043 @@ -3522,11 +3518,11 @@ "code": 6192, "reportsUnnecessary": true }, - "Found 1 error.": { + "Found 1 error. Watching for file changes.": { "category": "Message", "code": 6193 }, - "Found {0} errors.": { + "Found {0} errors. Watching for file changes.": { "category": "Message", "code": 6194 }, diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 7f3d078b790..37aa0118801 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -29,9 +29,8 @@ namespace ts { /** @internal */ export const nonClearingMessageCodes: number[] = [ - Diagnostics.Compilation_complete_Watching_for_file_changes.code, - Diagnostics.Found_1_error.code, - Diagnostics.Found_0_errors.code + Diagnostics.Found_1_error_Watching_for_file_changes.code, + Diagnostics.Found_0_errors_Watching_for_file_changes.code ]; function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions) { @@ -231,10 +230,10 @@ namespace ts { const reportSummary = (errorCount: number) => { if (errorCount === 1) { - onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_1_error, errorCount), newLine, compilerOptions); + onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes, errorCount), newLine, compilerOptions); } else { - onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_0_errors, errorCount, errorCount), newLine, compilerOptions); + onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errorCount, errorCount), newLine, compilerOptions); } }; @@ -644,7 +643,7 @@ namespace ts { if (host.afterProgramCreate) { host.afterProgramCreate(builderProgram); } - reportWatchDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes); + return builderProgram; } diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 99bad3e3091..c8faba855dc 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -130,8 +130,8 @@ namespace ts.tscWatch { function createErrorsFoundCompilerDiagnostic(errors: ReadonlyArray) { return errors.length === 1 - ? createCompilerDiagnostic(Diagnostics.Found_1_error) - : createCompilerDiagnostic(Diagnostics.Found_0_errors, errors.length); + ? createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes) + : createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errors.length); } function checkOutputErrorsInitial(host: WatchedSystem, errors: ReadonlyArray, disableConsoleClears?: boolean, logsBeforeErrors?: string[]) { @@ -142,8 +142,7 @@ namespace ts.tscWatch { logsBeforeErrors, errors, disableConsoleClears, - createErrorsFoundCompilerDiagnostic(errors), - createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes)); + createErrorsFoundCompilerDiagnostic(errors)); } function checkOutputErrorsIncremental(host: WatchedSystem, errors: ReadonlyArray, disableConsoleClears?: boolean, logsBeforeWatchDiagnostic?: string[], logsBeforeErrors?: string[]) { @@ -154,8 +153,7 @@ namespace ts.tscWatch { logsBeforeErrors, errors, disableConsoleClears, - createErrorsFoundCompilerDiagnostic(errors), - createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes)); + createErrorsFoundCompilerDiagnostic(errors)); } function checkOutputErrorsIncrementalWithExit(host: WatchedSystem, errors: ReadonlyArray, expectedExitCode: ExitStatus, disableConsoleClears?: boolean, logsBeforeWatchDiagnostic?: string[], logsBeforeErrors?: string[]) { From e35336c1182360f0ed4cc2bc987f858abfc3372d Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 17 Apr 2018 10:10:39 +0000 Subject: [PATCH 073/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index 473da1a4a01..3252fe24f15 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3887,6 +3887,15 @@ + + + + + + + + + @@ -5996,6 +6005,9 @@ + + + From 6798d56472f656a2f9633963f8b99eae68286a7e Mon Sep 17 00:00:00 2001 From: falsandtru Date: Tue, 17 Apr 2018 23:08:06 +0900 Subject: [PATCH 074/229] Fix Promise.reject --- src/lib/es2015.promise.d.ts | 9 +- tests/baselines/reference/promiseType.symbols | 96 +++++++++---------- tests/baselines/reference/promiseType.types | 96 +++++++++---------- .../reference/promiseTypeStrictNull.symbols | 96 +++++++++---------- .../reference/promiseTypeStrictNull.types | 96 +++++++++---------- 5 files changed, 193 insertions(+), 200 deletions(-) diff --git a/src/lib/es2015.promise.d.ts b/src/lib/es2015.promise.d.ts index ab33531191f..14602c0b5ed 100644 --- a/src/lib/es2015.promise.d.ts +++ b/src/lib/es2015.promise.d.ts @@ -177,14 +177,7 @@ interface PromiseConstructor { * @param reason The reason the promise was rejected. * @returns A new rejected Promise. */ - reject(reason: any): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; + reject(reason?: any): Promise; /** * Creates a new resolved promise for the provided value. diff --git a/tests/baselines/reference/promiseType.symbols b/tests/baselines/reference/promiseType.symbols index 5eea680f9fb..f33d26b8506 100644 --- a/tests/baselines/reference/promiseType.symbols +++ b/tests/baselines/reference/promiseType.symbols @@ -91,9 +91,9 @@ async function F() { >e : Symbol(e, Decl(promiseType.ts, 47, 11)) return Promise.reject(Error()); ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) } } @@ -150,9 +150,9 @@ async function I() { >e : Symbol(e, Decl(promiseType.ts, 77, 11)) return Promise.reject(Error()); ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) } } @@ -227,9 +227,9 @@ const p18 = p.catch(() => Promise.reject(1)); >p.catch : Symbol(Promise.catch, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >catch : Symbol(Promise.catch, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p19 = p.catch(() => Promise.resolve(1)); >p19 : Symbol(p19, Decl(promiseType.ts, 96, 5)) @@ -305,9 +305,9 @@ const p29 = p.then(() => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p30 = p.then(undefined, undefined); >p30 : Symbol(p30, Decl(promiseType.ts, 109, 5)) @@ -384,9 +384,9 @@ const p39 = p.then(undefined, () => Promise.reject(1)); >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >undefined : Symbol(undefined) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p40 = p.then(null, undefined); >p40 : Symbol(p40, Decl(promiseType.ts, 120, 5)) @@ -453,9 +453,9 @@ const p49 = p.then(null, () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p50 = p.then(() => "1", undefined); >p50 : Symbol(p50, Decl(promiseType.ts, 131, 5)) @@ -522,9 +522,9 @@ const p59 = p.then(() => "1", () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p60 = p.then(() => x, undefined); >p60 : Symbol(p60, Decl(promiseType.ts, 142, 5)) @@ -601,9 +601,9 @@ const p69 = p.then(() => x, () => Promise.reject(1)); >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >x : Symbol(x, Decl(promiseType.ts, 1, 11)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p70 = p.then(() => undefined, undefined); >p70 : Symbol(p70, Decl(promiseType.ts, 153, 5)) @@ -680,9 +680,9 @@ const p79 = p.then(() => undefined, () => Promise.reject(1)); >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >undefined : Symbol(undefined) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p80 = p.then(() => null, undefined); >p80 : Symbol(p80, Decl(promiseType.ts, 164, 5)) @@ -749,9 +749,9 @@ const p89 = p.then(() => null, () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p90 = p.then(() => {}, undefined); >p90 : Symbol(p90, Decl(promiseType.ts, 175, 5)) @@ -818,9 +818,9 @@ const p99 = p.then(() => {}, () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pa0 = p.then(() => {throw 1}, undefined); >pa0 : Symbol(pa0, Decl(promiseType.ts, 186, 5)) @@ -887,9 +887,9 @@ const pa9 = p.then(() => {throw 1}, () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pb0 = p.then(() => Promise.resolve("1"), undefined); >pb0 : Symbol(pb0, Decl(promiseType.ts, 197, 5)) @@ -986,18 +986,18 @@ const pb9 = p.then(() => Promise.resolve("1"), () => Promise.reject(1)); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc0 = p.then(() => Promise.reject("1"), undefined); >pc0 : Symbol(pc0, Decl(promiseType.ts, 208, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >undefined : Symbol(undefined) const pc1 = p.then(() => Promise.reject("1"), null); @@ -1005,27 +1005,27 @@ const pc1 = p.then(() => Promise.reject("1"), null); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc2 = p.then(() => Promise.reject("1"), () => 1); >pc2 : Symbol(pc2, Decl(promiseType.ts, 210, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc3 = p.then(() => Promise.reject("1"), () => x); >pc3 : Symbol(pc3, Decl(promiseType.ts, 211, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >x : Symbol(x, Decl(promiseType.ts, 1, 11)) const pc4 = p.then(() => Promise.reject("1"), () => undefined); @@ -1033,9 +1033,9 @@ const pc4 = p.then(() => Promise.reject("1"), () => undefined); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >undefined : Symbol(undefined) const pc5 = p.then(() => Promise.reject("1"), () => null); @@ -1043,36 +1043,36 @@ const pc5 = p.then(() => Promise.reject("1"), () => null); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc6 = p.then(() => Promise.reject("1"), () => {}); >pc6 : Symbol(pc6, Decl(promiseType.ts, 214, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc7 = p.then(() => Promise.reject("1"), () => {throw 1}); >pc7 : Symbol(pc7, Decl(promiseType.ts, 215, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc8 = p.then(() => Promise.reject("1"), () => Promise.resolve(1)); >pc8 : Symbol(pc8, Decl(promiseType.ts, 216, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) @@ -1082,10 +1082,10 @@ const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseType.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) diff --git a/tests/baselines/reference/promiseType.types b/tests/baselines/reference/promiseType.types index 3228d266319..f5674143bb8 100644 --- a/tests/baselines/reference/promiseType.types +++ b/tests/baselines/reference/promiseType.types @@ -105,9 +105,9 @@ async function F() { return Promise.reject(Error()); >Promise.reject(Error()) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >Error() : Error >Error : ErrorConstructor } @@ -170,9 +170,9 @@ async function I() { return Promise.reject(Error()); >Promise.reject(Error()) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >Error() : Error >Error : ErrorConstructor } @@ -271,9 +271,9 @@ const p18 = p.catch(() => Promise.reject(1)); >catch : (onrejected?: (reason: any) => TResult | PromiseLike) => Promise >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p19 = p.catch(() => Promise.resolve(1)); @@ -379,9 +379,9 @@ const p29 = p.then(() => Promise.reject(1)); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p30 = p.then(undefined, undefined); @@ -484,9 +484,9 @@ const p39 = p.then(undefined, () => Promise.reject(1)); >undefined : undefined >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p40 = p.then(null, undefined); @@ -589,9 +589,9 @@ const p49 = p.then(null, () => Promise.reject(1)); >null : null >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p50 = p.then(() => "1", undefined); @@ -704,9 +704,9 @@ const p59 = p.then(() => "1", () => Promise.reject(1)); >"1" : "1" >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p60 = p.then(() => x, undefined); @@ -819,9 +819,9 @@ const p69 = p.then(() => x, () => Promise.reject(1)); >x : any >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p70 = p.then(() => undefined, undefined); @@ -934,9 +934,9 @@ const p79 = p.then(() => undefined, () => Promise.reject(1)); >undefined : undefined >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p80 = p.then(() => null, undefined); @@ -1049,9 +1049,9 @@ const p89 = p.then(() => null, () => Promise.reject(1)); >null : null >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p90 = p.then(() => {}, undefined); @@ -1154,9 +1154,9 @@ const p99 = p.then(() => {}, () => Promise.reject(1)); >() => {} : () => void >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const pa0 = p.then(() => {throw 1}, undefined); @@ -1269,9 +1269,9 @@ const pa9 = p.then(() => {throw 1}, () => Promise.reject(1)); >1 : 1 >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const pb0 = p.then(() => Promise.resolve("1"), undefined); @@ -1424,9 +1424,9 @@ const pb9 = p.then(() => Promise.resolve("1"), () => Promise.reject(1)); >"1" : "1" >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const pc0 = p.then(() => Promise.reject("1"), undefined); @@ -1437,9 +1437,9 @@ const pc0 = p.then(() => Promise.reject("1"), undefined); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >undefined : undefined @@ -1451,9 +1451,9 @@ const pc1 = p.then(() => Promise.reject("1"), null); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >null : null @@ -1465,9 +1465,9 @@ const pc2 = p.then(() => Promise.reject("1"), () => 1); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => 1 : () => number >1 : 1 @@ -1480,9 +1480,9 @@ const pc3 = p.then(() => Promise.reject("1"), () => x); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => x : () => any >x : any @@ -1495,9 +1495,9 @@ const pc4 = p.then(() => Promise.reject("1"), () => undefined); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => undefined : () => any >undefined : undefined @@ -1510,9 +1510,9 @@ const pc5 = p.then(() => Promise.reject("1"), () => null); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => null : () => any >null : null @@ -1525,9 +1525,9 @@ const pc6 = p.then(() => Promise.reject("1"), () => {}); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => {} : () => void @@ -1539,9 +1539,9 @@ const pc7 = p.then(() => Promise.reject("1"), () => {throw 1}); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => {throw 1} : () => never >1 : 1 @@ -1554,9 +1554,9 @@ const pc8 = p.then(() => Promise.reject("1"), () => Promise.resolve(1)); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => Promise.resolve(1) : () => Promise >Promise.resolve(1) : Promise @@ -1573,14 +1573,14 @@ const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); >then : (onfulfilled?: (value: boolean) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 diff --git a/tests/baselines/reference/promiseTypeStrictNull.symbols b/tests/baselines/reference/promiseTypeStrictNull.symbols index 3fabb7f16b7..30609978642 100644 --- a/tests/baselines/reference/promiseTypeStrictNull.symbols +++ b/tests/baselines/reference/promiseTypeStrictNull.symbols @@ -91,9 +91,9 @@ async function F() { >e : Symbol(e, Decl(promiseTypeStrictNull.ts, 47, 11)) return Promise.reject(Error()); ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) } } @@ -150,9 +150,9 @@ async function I() { >e : Symbol(e, Decl(promiseTypeStrictNull.ts, 77, 11)) return Promise.reject(Error()); ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) } } @@ -227,9 +227,9 @@ const p18 = p.catch(() => Promise.reject(1)); >p.catch : Symbol(Promise.catch, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >catch : Symbol(Promise.catch, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p19 = p.catch(() => Promise.resolve(1)); >p19 : Symbol(p19, Decl(promiseTypeStrictNull.ts, 96, 5)) @@ -305,9 +305,9 @@ const p29 = p.then(() => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p30 = p.then(undefined, undefined); >p30 : Symbol(p30, Decl(promiseTypeStrictNull.ts, 109, 5)) @@ -384,9 +384,9 @@ const p39 = p.then(undefined, () => Promise.reject(1)); >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >undefined : Symbol(undefined) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p40 = p.then(null, undefined); >p40 : Symbol(p40, Decl(promiseTypeStrictNull.ts, 120, 5)) @@ -453,9 +453,9 @@ const p49 = p.then(null, () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p50 = p.then(() => "1", undefined); >p50 : Symbol(p50, Decl(promiseTypeStrictNull.ts, 131, 5)) @@ -522,9 +522,9 @@ const p59 = p.then(() => "1", () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p60 = p.then(() => x, undefined); >p60 : Symbol(p60, Decl(promiseTypeStrictNull.ts, 142, 5)) @@ -601,9 +601,9 @@ const p69 = p.then(() => x, () => Promise.reject(1)); >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >x : Symbol(x, Decl(promiseTypeStrictNull.ts, 1, 11)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p70 = p.then(() => undefined, undefined); >p70 : Symbol(p70, Decl(promiseTypeStrictNull.ts, 153, 5)) @@ -680,9 +680,9 @@ const p79 = p.then(() => undefined, () => Promise.reject(1)); >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >undefined : Symbol(undefined) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p80 = p.then(() => null, undefined); >p80 : Symbol(p80, Decl(promiseTypeStrictNull.ts, 164, 5)) @@ -749,9 +749,9 @@ const p89 = p.then(() => null, () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const p90 = p.then(() => {}, undefined); >p90 : Symbol(p90, Decl(promiseTypeStrictNull.ts, 175, 5)) @@ -818,9 +818,9 @@ const p99 = p.then(() => {}, () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pa0 = p.then(() => {throw 1}, undefined); >pa0 : Symbol(pa0, Decl(promiseTypeStrictNull.ts, 186, 5)) @@ -887,9 +887,9 @@ const pa9 = p.then(() => {throw 1}, () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pb0 = p.then(() => Promise.resolve("1"), undefined); >pb0 : Symbol(pb0, Decl(promiseTypeStrictNull.ts, 197, 5)) @@ -986,18 +986,18 @@ const pb9 = p.then(() => Promise.resolve("1"), () => Promise.reject(1)); >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc0 = p.then(() => Promise.reject("1"), undefined); >pc0 : Symbol(pc0, Decl(promiseTypeStrictNull.ts, 208, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >undefined : Symbol(undefined) const pc1 = p.then(() => Promise.reject("1"), null); @@ -1005,27 +1005,27 @@ const pc1 = p.then(() => Promise.reject("1"), null); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc2 = p.then(() => Promise.reject("1"), () => 1); >pc2 : Symbol(pc2, Decl(promiseTypeStrictNull.ts, 210, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc3 = p.then(() => Promise.reject("1"), () => x); >pc3 : Symbol(pc3, Decl(promiseTypeStrictNull.ts, 211, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >x : Symbol(x, Decl(promiseTypeStrictNull.ts, 1, 11)) const pc4 = p.then(() => Promise.reject("1"), () => undefined); @@ -1033,9 +1033,9 @@ const pc4 = p.then(() => Promise.reject("1"), () => undefined); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >undefined : Symbol(undefined) const pc5 = p.then(() => Promise.reject("1"), () => null); @@ -1043,36 +1043,36 @@ const pc5 = p.then(() => Promise.reject("1"), () => null); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc6 = p.then(() => Promise.reject("1"), () => {}); >pc6 : Symbol(pc6, Decl(promiseTypeStrictNull.ts, 214, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc7 = p.then(() => Promise.reject("1"), () => {throw 1}); >pc7 : Symbol(pc7, Decl(promiseTypeStrictNull.ts, 215, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) const pc8 = p.then(() => Promise.reject("1"), () => Promise.resolve(1)); >pc8 : Symbol(pc8, Decl(promiseTypeStrictNull.ts, 216, 5)) >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) >resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) @@ -1082,10 +1082,10 @@ const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); >p.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >p : Symbol(p, Decl(promiseTypeStrictNull.ts, 0, 11)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) +>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) ->reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --)) +>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --)) diff --git a/tests/baselines/reference/promiseTypeStrictNull.types b/tests/baselines/reference/promiseTypeStrictNull.types index 7bb75ec66f2..99c16c0b511 100644 --- a/tests/baselines/reference/promiseTypeStrictNull.types +++ b/tests/baselines/reference/promiseTypeStrictNull.types @@ -105,9 +105,9 @@ async function F() { return Promise.reject(Error()); >Promise.reject(Error()) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >Error() : Error >Error : ErrorConstructor } @@ -170,9 +170,9 @@ async function I() { return Promise.reject(Error()); >Promise.reject(Error()) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >Error() : Error >Error : ErrorConstructor } @@ -271,9 +271,9 @@ const p18 = p.catch(() => Promise.reject(1)); >catch : (onrejected?: ((reason: any) => TResult | PromiseLike) | null | undefined) => Promise >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p19 = p.catch(() => Promise.resolve(1)); @@ -379,9 +379,9 @@ const p29 = p.then(() => Promise.reject(1)); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p30 = p.then(undefined, undefined); @@ -484,9 +484,9 @@ const p39 = p.then(undefined, () => Promise.reject(1)); >undefined : undefined >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p40 = p.then(null, undefined); @@ -589,9 +589,9 @@ const p49 = p.then(null, () => Promise.reject(1)); >null : null >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p50 = p.then(() => "1", undefined); @@ -704,9 +704,9 @@ const p59 = p.then(() => "1", () => Promise.reject(1)); >"1" : "1" >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p60 = p.then(() => x, undefined); @@ -819,9 +819,9 @@ const p69 = p.then(() => x, () => Promise.reject(1)); >x : any >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p70 = p.then(() => undefined, undefined); @@ -934,9 +934,9 @@ const p79 = p.then(() => undefined, () => Promise.reject(1)); >undefined : undefined >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p80 = p.then(() => null, undefined); @@ -1049,9 +1049,9 @@ const p89 = p.then(() => null, () => Promise.reject(1)); >null : null >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const p90 = p.then(() => {}, undefined); @@ -1154,9 +1154,9 @@ const p99 = p.then(() => {}, () => Promise.reject(1)); >() => {} : () => void >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const pa0 = p.then(() => {throw 1}, undefined); @@ -1269,9 +1269,9 @@ const pa9 = p.then(() => {throw 1}, () => Promise.reject(1)); >1 : 1 >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const pb0 = p.then(() => Promise.resolve("1"), undefined); @@ -1424,9 +1424,9 @@ const pb9 = p.then(() => Promise.resolve("1"), () => Promise.reject(1)); >"1" : "1" >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 const pc0 = p.then(() => Promise.reject("1"), undefined); @@ -1437,9 +1437,9 @@ const pc0 = p.then(() => Promise.reject("1"), undefined); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >undefined : undefined @@ -1451,9 +1451,9 @@ const pc1 = p.then(() => Promise.reject("1"), null); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >null : null @@ -1465,9 +1465,9 @@ const pc2 = p.then(() => Promise.reject("1"), () => 1); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => 1 : () => number >1 : 1 @@ -1480,9 +1480,9 @@ const pc3 = p.then(() => Promise.reject("1"), () => x); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => x : () => any >x : any @@ -1495,9 +1495,9 @@ const pc4 = p.then(() => Promise.reject("1"), () => undefined); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => undefined : () => undefined >undefined : undefined @@ -1510,9 +1510,9 @@ const pc5 = p.then(() => Promise.reject("1"), () => null); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => null : () => null >null : null @@ -1525,9 +1525,9 @@ const pc6 = p.then(() => Promise.reject("1"), () => {}); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => {} : () => void @@ -1539,9 +1539,9 @@ const pc7 = p.then(() => Promise.reject("1"), () => {throw 1}); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => {throw 1} : () => never >1 : 1 @@ -1554,9 +1554,9 @@ const pc8 = p.then(() => Promise.reject("1"), () => Promise.resolve(1)); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => Promise.resolve(1) : () => Promise >Promise.resolve(1) : Promise @@ -1573,14 +1573,14 @@ const pc9 = p.then(() => Promise.reject("1"), () => Promise.reject(1)); >then : (onfulfilled?: ((value: boolean) => TResult1 | PromiseLike) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null | undefined) => Promise >() => Promise.reject("1") : () => Promise >Promise.reject("1") : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >"1" : "1" >() => Promise.reject(1) : () => Promise >Promise.reject(1) : Promise ->Promise.reject : { (reason: any): Promise; (reason: any): Promise; } +>Promise.reject : (reason?: any) => Promise >Promise : PromiseConstructor ->reject : { (reason: any): Promise; (reason: any): Promise; } +>reject : (reason?: any) => Promise >1 : 1 From bc285aa9a1ce8599d38dcf00583028e216f08c0d Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 07:53:43 -0700 Subject: [PATCH 075/229] findAllReferences: Mark *every* search symbol as seen, not just search.symbol (#23451) --- src/services/findAllReferences.ts | 26 ++++++++++--------- .../findAllReferencesDynamicImport3.ts | 16 ++++++------ 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 7c5922035ea..268af57e5a3 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -424,7 +424,8 @@ namespace ts.FindAllReferences.Core { readonly text: string; readonly escapedText: __String; /** Only set if `options.implementations` is true. These are the symbols checked to get the implementations of a property access. */ - readonly parents: Symbol[] | undefined; + readonly parents: ReadonlyArray | undefined; + readonly allSearchSymbols: ReadonlyArray; /** * Whether a symbol is in the search set. @@ -500,14 +501,11 @@ namespace ts.FindAllReferences.Core { // here appears to be intentional). const { text = stripQuotes(unescapeLeadingUnderscores((getLocalSymbolForExportDefault(symbol) || symbol).escapedName)), - allSearchSymbols, + allSearchSymbols = [symbol], } = searchOptions; const escapedText = escapeLeadingUnderscores(text); const parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker); - return { - symbol, comingFrom, text, escapedText, parents, - includes: referenceSymbol => allSearchSymbols ? contains(allSearchSymbols, referenceSymbol) : referenceSymbol === symbol, - }; + return { symbol, comingFrom, text, escapedText, parents, allSearchSymbols, includes: sym => contains(allSearchSymbols, sym) }; } private readonly symbolIdToReferences: Entry[][] = []; @@ -534,13 +532,17 @@ namespace ts.FindAllReferences.Core { } // Source file ID → symbol ID → Whether the symbol has been searched for in the source file. - private readonly sourceFileToSeenSymbols: true[][] = []; + private readonly sourceFileToSeenSymbols: Map[] = []; /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */ - markSearchedSymbol(sourceFile: SourceFile, symbol: Symbol): boolean { + markSearchedSymbols(sourceFile: SourceFile, symbols: ReadonlyArray): boolean { const sourceId = getNodeId(sourceFile); - const symbolId = getSymbolId(symbol); - const seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = []); - return !seenSymbols[symbolId] && (seenSymbols[symbolId] = true); + const seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = createMap()); + + let anyNewSymbols = false; + for (const sym of symbols) { + anyNewSymbols = addToSeen(seenSymbols, getSymbolId(sym)) || anyNewSymbols; + } + return anyNewSymbols; } } @@ -804,7 +806,7 @@ namespace ts.FindAllReferences.Core { * searchLocation: a node where the search value */ function getReferencesInContainer(container: Node, sourceFile: SourceFile, search: Search, state: State, addReferencesHere: boolean): void { - if (!state.markSearchedSymbol(sourceFile, search.symbol)) { + if (!state.markSearchedSymbols(sourceFile, search.allSearchSymbols)) { return; } diff --git a/tests/cases/fourslash/findAllReferencesDynamicImport3.ts b/tests/cases/fourslash/findAllReferencesDynamicImport3.ts index 21d2e1097db..636e640ceb3 100644 --- a/tests/cases/fourslash/findAllReferencesDynamicImport3.ts +++ b/tests/cases/fourslash/findAllReferencesDynamicImport3.ts @@ -1,13 +1,13 @@ /// // @Filename: foo.ts -//// export function [|bar|]() { return "bar"; } - -//// import('./foo').then(({ [|bar|] }) => undefined); +////export function [|{| "isWriteAccess": true, "isDefinition": true |}bar|]() { return "bar"; } +////import('./foo').then(({ [|{| "isWriteAccess": true, "isDefinition": true |}bar|] }) => undefined); const [r0, r1] = test.ranges(); -// This is because bindingElement at r1 are both name and value -verify.referencesOf(r0, [r1, r0, r1, r0]); -verify.referencesOf(r1, [r0, r1, r1, r0]); -verify.renameLocations(r0, [r0, r1]); -verify.renameLocations(r1, [r1, r0, r0, r1]); \ No newline at end of file +verify.referenceGroups(r0, [{ definition: "function bar(): string", ranges: [r0, r1] }]); +verify.referenceGroups(r1, [ + { definition: "function bar(): string", ranges: [r0] }, + { definition: "var bar: () => string", ranges: [r1] }, +]); +verify.rangesAreRenameLocations(); From bc9ad90a81fc30424d3c2bc211ac17ff15e256ae Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 17 Apr 2018 08:28:12 -0700 Subject: [PATCH 076/229] Adjusted newlines in non-pretty output for consistency Fixes #23469 --- src/compiler/watch.ts | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 7f3d078b790..f125fab5a5e 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -44,6 +44,24 @@ namespace ts { } } + /** @internal */ + const screenStartingMessageCodes: number[] = [ + Diagnostics.Starting_compilation_in_watch_mode.code, + Diagnostics.File_change_detected_Starting_incremental_compilation.code, + ]; + + function getPlainDiagnosticPrecedingNewLines(diagnostic: Diagnostic, newLine: string): string { + return contains(screenStartingMessageCodes, diagnostic.code) + ? "" + : newLine; + } + + function getPlainDiagnosticFollowingNewLines(diagnostic: Diagnostic, newLine: string): string { + return contains(screenStartingMessageCodes, diagnostic.code) + ? newLine + newLine + : newLine; + } + /** * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic */ @@ -52,13 +70,13 @@ namespace ts { (diagnostic, newLine, options) => { clearScreenIfNotWatchingForFileChanges(system, diagnostic, options); let output = `[${formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey)}] `; - output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`; + output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine}`; system.write(output); } : (diagnostic, newLine, options) => { clearScreenIfNotWatchingForFileChanges(system, diagnostic, options); - let output = new Date().toLocaleTimeString() + " - "; - output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`; + let output = `${getPlainDiagnosticPrecedingNewLines(diagnostic, newLine)}${new Date().toLocaleTimeString()} - `; + output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${getPlainDiagnosticFollowingNewLines(diagnostic, newLine)}`; system.write(output); }; } From c974b2ced7b284557577b5a8a477f3376723cd70 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 17 Apr 2018 08:57:05 -0700 Subject: [PATCH 077/229] Helps to check in the test changes, too --- src/compiler/watch.ts | 2 +- src/harness/unittests/tscWatchMode.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index f125fab5a5e..330aeaaa840 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -45,7 +45,7 @@ namespace ts { } /** @internal */ - const screenStartingMessageCodes: number[] = [ + export const screenStartingMessageCodes: number[] = [ Diagnostics.Starting_compilation_in_watch_mode.code, Diagnostics.File_change_detected_Starting_incremental_compilation.code, ]; diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 99bad3e3091..d57a8e9b6d0 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -124,7 +124,10 @@ namespace ts.tscWatch { } function getWatchDiagnosticWithoutDate(diagnostic: Diagnostic) { - return ` - ${flattenDiagnosticMessageText(diagnostic.messageText, host.newLine)}${host.newLine + host.newLine + host.newLine}`; + const newLines = contains(screenStartingMessageCodes, diagnostic.code) + ? `${host.newLine}${host.newLine}` + : host.newLine; + return ` - ${flattenDiagnosticMessageText(diagnostic.messageText, host.newLine)}${newLines}`; } } From 55f9a6ffc260798c87ab4420549456a9b28c8f02 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 08:59:07 -0700 Subject: [PATCH 078/229] Fix bug: VariableDeclaration initiazer may be undefined (#23439) --- src/services/codefixes/convertToEs6Module.ts | 32 +++++++++---------- ...orConvertToEs6Module_missingInitializer.ts | 14 ++++++++ 2 files changed, 30 insertions(+), 16 deletions(-) create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts diff --git a/src/services/codefixes/convertToEs6Module.ts b/src/services/codefixes/convertToEs6Module.ts index 8ffba3218c0..a8df21dc96d 100644 --- a/src/services/codefixes/convertToEs6Module.ts +++ b/src/services/codefixes/convertToEs6Module.ts @@ -130,23 +130,23 @@ namespace ts.codefix { let foundImport = false; const newNodes = flatMap(declarationList.declarations, decl => { const { name, initializer } = decl; - if (isExportsOrModuleExportsOrAlias(sourceFile, initializer)) { - // `const alias = module.exports;` can be removed. - foundImport = true; - return []; - } - if (isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) { - foundImport = true; - return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target); - } - else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) { - foundImport = true; - return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers); - } - else { - // Move it out to its own variable statement. (This will not be used if `!foundImport`) - return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags)); + if (initializer) { + if (isExportsOrModuleExportsOrAlias(sourceFile, initializer)) { + // `const alias = module.exports;` can be removed. + foundImport = true; + return []; + } + else if (isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) { + foundImport = true; + return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target); + } + else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) { + foundImport = true; + return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers); + } } + // Move it out to its own variable statement. (This will not be used if `!foundImport`) + return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags)); }); if (foundImport) { // useNonAdjustedEndPosition to ensure we don't eat the newline after the statement. diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts b/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts new file mode 100644 index 00000000000..77c4ce0fc43 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////require("m"); +////let x; x; + +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: +`import "m"; +let x; x;` +}); From e50b24a83beec5d4c1f81b9dcb8ea66534b20e49 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 09:15:05 -0700 Subject: [PATCH 079/229] convertFunctionToEs6Class: Copy comment from variable declaration (#23445) --- .../codefixes/convertFunctionToEs6Class.ts | 3 ++- ...ionToEs6Class_commentOnVariableDeclaration.ts | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/convertFunctionToEs6Class_commentOnVariableDeclaration.ts diff --git a/src/services/codefixes/convertFunctionToEs6Class.ts b/src/services/codefixes/convertFunctionToEs6Class.ts index bf20aeda72b..d137785a7e7 100644 --- a/src/services/codefixes/convertFunctionToEs6Class.ts +++ b/src/services/codefixes/convertFunctionToEs6Class.ts @@ -34,13 +34,14 @@ namespace ts.codefix { case SyntaxKind.VariableDeclaration: precedingNode = ctorDeclaration.parent.parent; + newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration as VariableDeclaration); if ((ctorDeclaration.parent).declarations.length === 1) { + copyComments(precedingNode, newClassDeclaration, sourceFile); deleteNode(precedingNode); } else { deleteNode(ctorDeclaration, /*inList*/ true); } - newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration as VariableDeclaration); break; } diff --git a/tests/cases/fourslash/convertFunctionToEs6Class_commentOnVariableDeclaration.ts b/tests/cases/fourslash/convertFunctionToEs6Class_commentOnVariableDeclaration.ts new file mode 100644 index 00000000000..417bf0bc905 --- /dev/null +++ b/tests/cases/fourslash/convertFunctionToEs6Class_commentOnVariableDeclaration.ts @@ -0,0 +1,16 @@ +/// + +// @allowJs: true +// @Filename: /a.js +/////** Doc */ +////const C = function() { this.x = 0; } + +verify.codeFix({ + description: "Convert function to an ES2015 class", + newFileContent: +`/** Doc */ +class C { + constructor() { this.x = 0; } +} +`, +}); From 3a8d66ba29202030324c3f8a96fcdfcbbeca5190 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Tue, 17 Apr 2018 09:20:34 -0700 Subject: [PATCH 080/229] Only normalize for purposes of assert --- src/services/services.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index bceb7f572af..11ccee93d6c 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1673,8 +1673,7 @@ namespace ts { } function getDocumentHighlights(fileName: string, position: number, filesToSearch: ReadonlyArray): DocumentHighlights[] { - filesToSearch = map(filesToSearch, normalizePath); - Debug.assert(contains(filesToSearch, fileName)); + Debug.assert(contains(map(filesToSearch, normalizePath), fileName)); synchronizeHostData(); const sourceFilesToSearch = map(filesToSearch, f => Debug.assertDefined(program.getSourceFile(f))); const sourceFile = getValidSourceFile(fileName); From 160356317b0bd475669e80a00fa4e7a72476a0ba Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Tue, 17 Apr 2018 09:20:52 -0700 Subject: [PATCH 081/229] Treat expectedRanges as readonly --- src/harness/fourslash.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index d2b389c4373..8800f78e6fd 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2910,10 +2910,6 @@ Actual: ${stringify(fullActual)}`); } private verifyDocumentHighlights(expectedRanges: Range[], fileNames: ReadonlyArray = [this.activeFile.fileName]) { - expectedRanges = ts.map(expectedRanges, r => { - r.fileName = ts.normalizePath(r.fileName); - return r; - }); fileNames = ts.map(fileNames, ts.normalizePath); const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNames) || []; @@ -2924,7 +2920,7 @@ Actual: ${stringify(fullActual)}`); } for (const fileName of fileNames) { - const expectedRangesInFile = expectedRanges.filter(r => r.fileName === fileName); + const expectedRangesInFile = expectedRanges.filter(r => ts.normalizePath(r.fileName) === fileName); const highlights = ts.find(documentHighlights, dh => dh.fileName === fileName); const spansInFile = highlights ? highlights.highlightSpans.sort((s1, s2) => s1.textSpan.start - s2.textSpan.start) : []; From 12f6e5232b4ca8b0a7b64fa328e46ac7099aeff1 Mon Sep 17 00:00:00 2001 From: uniqueiniquity Date: Tue, 17 Apr 2018 09:41:26 -0700 Subject: [PATCH 082/229] Remove unnecessary allocation --- src/services/services.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 11ccee93d6c..a192231405a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1673,7 +1673,7 @@ namespace ts { } function getDocumentHighlights(fileName: string, position: number, filesToSearch: ReadonlyArray): DocumentHighlights[] { - Debug.assert(contains(map(filesToSearch, normalizePath), fileName)); + Debug.assert(filesToSearch.some(f => normalizePath(f) === fileName)); synchronizeHostData(); const sourceFilesToSearch = map(filesToSearch, f => Debug.assertDefined(program.getSourceFile(f))); const sourceFile = getValidSourceFile(fileName); From d009d8efcffc85a0846b6c7008fc54f5bd635ab3 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 10:41:53 -0700 Subject: [PATCH 083/229] Fix bug: IfStatement#elseStatement can be undefined (#23467) --- src/services/outliningElementsCollector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 9d590ffef61..65888305d81 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -21,7 +21,7 @@ namespace ts.OutliningElementsCollector { if (span) out.push(span); depthRemaining--; - if (isIfStatement(n) && isIfStatement(n.elseStatement)) { + if (isIfStatement(n) && n.elseStatement && isIfStatement(n.elseStatement)) { // Consider an 'else if' to be on the same depth as the 'if'. walk(n.expression); walk(n.thenStatement); From db68075b670cc78a0db5ff8a62ab1e56a13aac25 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 17 Apr 2018 11:21:11 -0700 Subject: [PATCH 084/229] Add create-react-app and puppeteer user tests (#23471) * Add create-react-app * Add puppeteer Everything is broken now. I am going back to master to see if that fixes things. * Add puppeteer baseline * Add chalk override (gitignore was ignoring it) --- .gitmodules | 7 ++ src/harness/externalCompileRunner.ts | 2 +- .../reference/user/create-react-app.log | 79 ++++++++++++ tests/baselines/reference/user/puppeteer.log | 40 ++++++ tests/baselines/reference/user/uglify-js.log | 119 +++++++++--------- .../user/create-react-app/chalk-override.d.ts | 1 + .../user/create-react-app/create-react-app | 1 + tests/cases/user/create-react-app/test.json | 3 + .../cases/user/create-react-app/tsconfig.json | 20 +++ tests/cases/user/puppeteer/puppeteer | 1 + tests/cases/user/puppeteer/test.json | 3 + 11 files changed, 216 insertions(+), 60 deletions(-) create mode 100644 tests/baselines/reference/user/create-react-app.log create mode 100644 tests/baselines/reference/user/puppeteer.log create mode 100644 tests/cases/user/create-react-app/chalk-override.d.ts create mode 160000 tests/cases/user/create-react-app/create-react-app create mode 100644 tests/cases/user/create-react-app/test.json create mode 100644 tests/cases/user/create-react-app/tsconfig.json create mode 160000 tests/cases/user/puppeteer/puppeteer create mode 100644 tests/cases/user/puppeteer/test.json diff --git a/.gitmodules b/.gitmodules index f7632c4abbd..ccb2be81520 100644 --- a/.gitmodules +++ b/.gitmodules @@ -18,7 +18,14 @@ path = tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter url = https://github.com/Microsoft/TypeScript-WeChat-Starter.git ignore = all +[submodule "tests/cases/user/create-react-app/create-react-app"] + path = tests/cases/user/create-react-app/create-react-app + url = https://github.com/facebook/create-react-app.git + ignore = all [submodule "tests/cases/user/webpack/webpack"] path = tests/cases/user/webpack/webpack url = https://github.com/webpack/webpack.git ignore = all +[submodule "tests/cases/user/puppeteer/puppeteer"] + path = tests/cases/user/puppeteer/puppeteer + url = https://github.com/GoogleChrome/puppeteer.git diff --git a/src/harness/externalCompileRunner.ts b/src/harness/externalCompileRunner.ts index 1f945cfcc9c..3d07c69af85 100644 --- a/src/harness/externalCompileRunner.ts +++ b/src/harness/externalCompileRunner.ts @@ -66,7 +66,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase { if (fs.existsSync(path.join(cwd, "node_modules"))) { require("del").sync(path.join(cwd, "node_modules"), { force: true }); } - const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure + const install = cp.spawnSync(`npm`, ["i", "--ignore-scripts"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`); } const args = [path.join(__dirname, "tsc.js")]; diff --git a/tests/baselines/reference/user/create-react-app.log b/tests/baselines/reference/user/create-react-app.log new file mode 100644 index 00000000000..2fefa8b230e --- /dev/null +++ b/tests/baselines/reference/user/create-react-app.log @@ -0,0 +1,79 @@ +Exit Code: 1 +Standard output: +packages/babel-preset-react-app/dependencies.js(38,17): error TS2307: Cannot find module '@babel/preset-env'. +packages/babel-preset-react-app/dependencies.js(49,17): error TS2307: Cannot find module '@babel/preset-env'. +packages/babel-preset-react-app/index.js(52,17): error TS2307: Cannot find module '@babel/preset-env'. +packages/babel-preset-react-app/index.js(61,17): error TS2307: Cannot find module '@babel/preset-env'. +packages/babel-preset-react-app/index.js(74,17): error TS2307: Cannot find module '@babel/preset-react'. +packages/babel-preset-react-app/index.js(84,33): error TS2307: Cannot find module '@babel/preset-flow'. +packages/babel-preset-react-app/index.js(89,15): error TS2307: Cannot find module 'babel-plugin-macros'. +packages/babel-preset-react-app/index.js(93,15): error TS2307: Cannot find module '@babel/plugin-transform-destructuring'. +packages/babel-preset-react-app/index.js(98,17): error TS2307: Cannot find module '@babel/plugin-proposal-class-properties'. +packages/babel-preset-react-app/index.js(107,17): error TS2307: Cannot find module '@babel/plugin-proposal-object-rest-spread'. +packages/babel-preset-react-app/index.js(114,17): error TS2307: Cannot find module '@babel/plugin-transform-runtime'. +packages/babel-preset-react-app/index.js(123,17): error TS2307: Cannot find module 'babel-plugin-transform-react-remove-prop-types'. +packages/babel-preset-react-app/index.js(130,17): error TS2307: Cannot find module '@babel/plugin-transform-regenerator'. +packages/babel-preset-react-app/index.js(137,15): error TS2307: Cannot find module '@babel/plugin-syntax-dynamic-import'. +packages/babel-preset-react-app/index.js(140,17): error TS2307: Cannot find module 'babel-plugin-transform-dynamic-import'. +packages/confusing-browser-globals/test.js(14,1): error TS2304: Cannot find name 'it'. +packages/confusing-browser-globals/test.js(15,3): error TS2304: Cannot find name 'expect'. +packages/confusing-browser-globals/test.js(18,1): error TS2304: Cannot find name 'it'. +packages/confusing-browser-globals/test.js(19,3): error TS2304: Cannot find name 'expect'. +packages/create-react-app/createReactApp.js(37,37): error TS2307: Cannot find module 'validate-npm-package-name'. +packages/create-react-app/createReactApp.js(47,24): error TS2307: Cannot find module 'tar-pack'. +packages/create-react-app/createReactApp.js(49,28): error TS2307: Cannot find module 'hyperquest'. +packages/create-react-app/createReactApp.js(50,25): error TS2307: Cannot find module 'envinfo'. +packages/create-react-app/createReactApp.js(52,30): error TS2307: Cannot find module 'react-dev-utils/workspaceUtils'. +packages/create-react-app/createReactApp.js(53,29): error TS2307: Cannot find module './package.json'. +packages/create-react-app/createReactApp.js(771,20): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. + Type 'undefined' is not assignable to type 'string'. +packages/create-react-app/index.js(45,5): error TS2365: Operator '<' cannot be applied to types 'string' and 'number'. +packages/eslint-config-react-app/index.js(24,33): error TS2307: Cannot find module 'confusing-browser-globals'. +packages/react-dev-utils/FileSizeReporter.js(13,24): error TS2307: Cannot find module 'filesize'. +packages/react-dev-utils/FileSizeReporter.js(14,25): error TS2307: Cannot find module 'recursive-readdir'. +packages/react-dev-utils/FileSizeReporter.js(16,24): error TS2307: Cannot find module 'gzip-size'. +packages/react-dev-utils/WebpackDevServerUtils.js(9,25): error TS2307: Cannot find module 'address'. +packages/react-dev-utils/WebpackDevServerUtils.js(14,24): error TS2307: Cannot find module 'detect-port-alt'. +packages/react-dev-utils/WebpackDevServerUtils.js(15,24): error TS2307: Cannot find module 'is-root'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(12,1): error TS2304: Cannot find name 'describe'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(13,3): error TS2304: Cannot find name 'it'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(18,5): error TS2304: Cannot find name 'expect'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(19,5): error TS2304: Cannot find name 'expect'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(22,3): error TS2304: Cannot find name 'it'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(26,5): error TS2304: Cannot find name 'expect'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(29,3): error TS2304: Cannot find name 'it'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(36,5): error TS2304: Cannot find name 'expect'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(37,5): error TS2304: Cannot find name 'expect'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(40,3): error TS2304: Cannot find name 'it'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(46,5): error TS2304: Cannot find name 'expect'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(49,3): error TS2304: Cannot find name 'it'. +packages/react-dev-utils/__tests__/ignoredFiles.test.js(53,5): error TS2304: Cannot find name 'expect'. +packages/react-dev-utils/browsersHelper.js(9,30): error TS2307: Cannot find module 'browserslist'. +packages/react-dev-utils/browsersHelper.js(13,23): error TS2307: Cannot find module 'pkg-up'. +packages/react-dev-utils/browsersHelper.js(59,22): error TS2554: Expected 1 arguments, but got 0. +packages/react-dev-utils/browsersHelper.js(61,36): error TS2345: Argument of type 'Buffer' is not assignable to parameter of type 'string'. +packages/react-dev-utils/browsersHelper.js(97,25): error TS2538: Type 'undefined' cannot be used as an index type. +packages/react-dev-utils/checkRequiredFiles.js(19,34): error TS2339: Property 'F_OK' does not exist on type 'typeof import("fs")'. +packages/react-dev-utils/checkRequiredFiles.js(23,32): error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'string'. +packages/react-dev-utils/checkRequiredFiles.js(24,34): error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'string'. +packages/react-dev-utils/getProcessForPort.js(29,6): error TS2339: Property 'split' does not exist on type 'Buffer'. +packages/react-dev-utils/getProcessForPort.js(49,21): error TS2339: Property 'replace' does not exist on type 'Buffer'. +packages/react-dev-utils/getProcessForPort.js(63,5): error TS2339: Property 'trim' does not exist on type 'Buffer'. +packages/react-dev-utils/openBrowser.js(13,19): error TS2307: Cannot find module 'opn'. +packages/react-dev-utils/webpackHotDevClient.js(19,22): error TS2307: Cannot find module 'sockjs-client'. +packages/react-dev-utils/webpackHotDevClient.js(24,28): error TS2307: Cannot find module 'react-error-overlay'. +packages/react-dev-utils/webpackHotDevClient.js(31,14): error TS2339: Property 'encodeURIComponent' does not exist on type 'Window'. +packages/react-dev-utils/webpackHotDevClient.js(33,14): error TS2339: Property 'encodeURIComponent' does not exist on type 'Window'. +packages/react-dev-utils/webpackHotDevClient.js(35,14): error TS2339: Property 'encodeURIComponent' does not exist on type 'Window'. +packages/react-dev-utils/webpackHotDevClient.js(53,12): error TS2339: Property 'hot' does not exist on type 'NodeModule'. +packages/react-dev-utils/webpackHotDevClient.js(53,33): error TS2339: Property 'hot' does not exist on type 'NodeModule'. +packages/react-dev-utils/webpackHotDevClient.js(54,10): error TS2339: Property 'hot' does not exist on type 'NodeModule'. +packages/react-dev-utils/webpackHotDevClient.js(223,40): error TS2304: Cannot find name '__webpack_hash__'. +packages/react-dev-utils/webpackHotDevClient.js(228,17): error TS2339: Property 'hot' does not exist on type 'NodeModule'. +packages/react-dev-utils/webpackHotDevClient.js(233,15): error TS2339: Property 'hot' does not exist on type 'NodeModule'. +packages/react-dev-utils/webpackHotDevClient.js(261,23): error TS2339: Property 'hot' does not exist on type 'NodeModule'. +packages/react-dev-utils/workspaceUtils.js(11,25): error TS2307: Cannot find module 'find-pkg'. + + + +Standard error: diff --git a/tests/baselines/reference/user/puppeteer.log b/tests/baselines/reference/user/puppeteer.log new file mode 100644 index 00000000000..b2a53a08dd3 --- /dev/null +++ b/tests/baselines/reference/user/puppeteer.log @@ -0,0 +1,40 @@ +Exit Code: 1 +Standard output: +lib/Coverage.js(109,15): error TS2503: Cannot find namespace 'Protocol'. +lib/Coverage.js(196,15): error TS2503: Cannot find namespace 'Protocol'. +lib/ElementHandle.js(24,15): error TS2503: Cannot find namespace 'Protocol'. +lib/ElementHandle.js(83,29): error TS2503: Cannot find namespace 'Protocol'. +lib/EmulationManager.js(36,16): error TS2503: Cannot find namespace 'Protocol'. +lib/ExecutionContext.js(22,15): error TS2503: Cannot find namespace 'Protocol'. +lib/ExecutionContext.js(132,15): error TS2503: Cannot find namespace 'Protocol'. +lib/FrameManager.js(28,15): error TS2503: Cannot find namespace 'Protocol'. +lib/FrameManager.js(54,15): error TS2503: Cannot find namespace 'Protocol'. +lib/FrameManager.js(76,15): error TS2503: Cannot find namespace 'Protocol'. +lib/FrameManager.js(127,15): error TS2503: Cannot find namespace 'Protocol'. +lib/FrameManager.js(773,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(129,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(174,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(207,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(224,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(256,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(270,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(286,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(313,15): error TS2503: Cannot find namespace 'Protocol'. +lib/NetworkManager.js(640,13): error TS2503: Cannot find namespace 'Protocol'. +lib/Page.js(66,15): error TS2503: Cannot find namespace 'Protocol'. +lib/Page.js(185,15): error TS2503: Cannot find namespace 'Protocol'. +lib/Page.js(394,22): error TS2503: Cannot find namespace 'Protocol'. +lib/Page.js(407,15): error TS2503: Cannot find namespace 'Protocol'. +lib/Page.js(731,19): error TS2503: Cannot find namespace 'Protocol'. +lib/externs.d.ts(16,26): error TS2503: Cannot find namespace 'Protocol'. +lib/externs.d.ts(16,69): error TS2503: Cannot find namespace 'Protocol'. +lib/externs.d.ts(17,28): error TS2503: Cannot find namespace 'Protocol'. +lib/externs.d.ts(17,81): error TS2503: Cannot find namespace 'Protocol'. +lib/externs.d.ts(17,121): error TS2503: Cannot find namespace 'Protocol'. +lib/helper.js(59,15): error TS2503: Cannot find namespace 'Protocol'. +lib/helper.js(77,15): error TS2503: Cannot find namespace 'Protocol'. +lib/helper.js(101,15): error TS2503: Cannot find namespace 'Protocol'. + + + +Standard error: diff --git a/tests/baselines/reference/user/uglify-js.log b/tests/baselines/reference/user/uglify-js.log index b467514604a..66a1267e755 100644 --- a/tests/baselines/reference/user/uglify-js.log +++ b/tests/baselines/reference/user/uglify-js.log @@ -6,65 +6,66 @@ node_modules/uglify-js/lib/ast.js(858,5): error TS2322: Type '{ [x: string]: any Object literal may only specify known properties, but '_visit' does not exist in type 'TreeWalker'. Did you mean to write 'visit'? node_modules/uglify-js/lib/compress.js(165,27): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/compress.js(453,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(722,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(964,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(990,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'true | ((node: any) => any)' has no compatible call signatures. -node_modules/uglify-js/lib/compress.js(1074,53): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1114,112): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(1115,29): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(1124,87): error TS2322: Type 'false' is not assignable to type 'number'. -node_modules/uglify-js/lib/compress.js(1132,29): error TS2322: Type 'false' is not assignable to type 'never'. -node_modules/uglify-js/lib/compress.js(1185,38): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1278,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1374,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1406,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1820,44): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1998,19): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(2258,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(2998,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3011,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. -node_modules/uglify-js/lib/compress.js(3148,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3158,33): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3162,32): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3168,40): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3177,41): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3194,14): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3196,40): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3204,33): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3278,63): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3467,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3484,36): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3490,38): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3494,40): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3519,22): error TS2339: Property 'each' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3524,30): error TS2339: Property 'del' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3529,30): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3540,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3542,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3554,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3556,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3640,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(3642,36): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3659,22): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3679,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. -node_modules/uglify-js/lib/compress.js(3704,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3855,22): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4133,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(4217,22): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4545,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4552,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ [x: string]: any; get: () => string; toString: () => string; indent: () => void; indentation: (...'. -node_modules/uglify-js/lib/compress.js(4556,36): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(4561,41): error TS2339: Property 'get' does not exist on type 'string'. -node_modules/uglify-js/lib/compress.js(5040,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. -node_modules/uglify-js/lib/compress.js(5505,32): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5565,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5637,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5643,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5993,43): error TS2454: Variable 'property' is used before being assigned. -node_modules/uglify-js/lib/compress.js(6007,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6010,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. -node_modules/uglify-js/lib/compress.js(6017,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6070,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(734,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(976,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1002,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'true | ((node: any) => any)' has no compatible call signatures. +node_modules/uglify-js/lib/compress.js(1086,53): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1126,112): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(1127,29): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(1136,87): error TS2322: Type 'false' is not assignable to type 'number'. +node_modules/uglify-js/lib/compress.js(1144,29): error TS2322: Type 'false' is not assignable to type 'never'. +node_modules/uglify-js/lib/compress.js(1197,38): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1290,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1386,27): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1418,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1832,44): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(2024,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(2284,27): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3024,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3037,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. +node_modules/uglify-js/lib/compress.js(3174,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3184,33): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3188,32): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3194,40): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3203,41): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3220,14): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3222,40): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3230,33): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3304,63): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3493,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3510,36): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3516,38): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3520,40): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3545,22): error TS2339: Property 'each' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3550,30): error TS2339: Property 'del' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3555,30): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3566,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3568,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3580,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3582,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3688,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(3690,36): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3719,22): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3739,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. +node_modules/uglify-js/lib/compress.js(3764,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3902,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4201,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(4285,22): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4613,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4620,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ [x: string]: any; get: () => string; toString: () => string; indent: () => void; indentation: (...'. +node_modules/uglify-js/lib/compress.js(4624,36): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(4629,41): error TS2339: Property 'get' does not exist on type 'string'. +node_modules/uglify-js/lib/compress.js(5114,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. +node_modules/uglify-js/lib/compress.js(5553,25): error TS2365: Operator '==' cannot be applied to types 'boolean' and '"f"'. +node_modules/uglify-js/lib/compress.js(5580,32): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5640,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5712,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5718,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(6068,43): error TS2454: Variable 'property' is used before being assigned. +node_modules/uglify-js/lib/compress.js(6082,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6085,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. +node_modules/uglify-js/lib/compress.js(6092,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6145,19): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/minify.js(166,75): error TS2339: Property 'compress' does not exist on type 'Compressor'. node_modules/uglify-js/lib/mozilla-ast.js(569,18): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/output.js(473,22): error TS2554: Expected 0 arguments, but got 1. diff --git a/tests/cases/user/create-react-app/chalk-override.d.ts b/tests/cases/user/create-react-app/chalk-override.d.ts new file mode 100644 index 00000000000..5adfd6d3cfb --- /dev/null +++ b/tests/cases/user/create-react-app/chalk-override.d.ts @@ -0,0 +1 @@ +declare module 'chalk'; diff --git a/tests/cases/user/create-react-app/create-react-app b/tests/cases/user/create-react-app/create-react-app new file mode 160000 index 00000000000..1d4fdc2dd49 --- /dev/null +++ b/tests/cases/user/create-react-app/create-react-app @@ -0,0 +1 @@ +Subproject commit 1d4fdc2dd4950011beacf1883900bf5d8da7079e diff --git a/tests/cases/user/create-react-app/test.json b/tests/cases/user/create-react-app/test.json new file mode 100644 index 00000000000..e0d4d26bdca --- /dev/null +++ b/tests/cases/user/create-react-app/test.json @@ -0,0 +1,3 @@ +{ + "types": [] +} diff --git a/tests/cases/user/create-react-app/tsconfig.json b/tests/cases/user/create-react-app/tsconfig.json new file mode 100644 index 00000000000..0bb5948b878 --- /dev/null +++ b/tests/cases/user/create-react-app/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "noImplicitAny": false, + "noImplicitThis": false, + "maxNodeModuleJsDepth": 0, + "strict": true, + "noEmit": true, + "allowJs": true, + "checkJs": true, + "types": ["node"], + "lib": ["esnext", "dom"], + "baseUrl": "./", + "paths": { + "chalk": ["chalk-override"] + } + }, + "include": ["create-react-app"], + "exclude": ["create-react-app/packages/react-error-overlay", + "create-react-app/packages/react-scripts"] +} diff --git a/tests/cases/user/puppeteer/puppeteer b/tests/cases/user/puppeteer/puppeteer new file mode 160000 index 00000000000..98bb2615adb --- /dev/null +++ b/tests/cases/user/puppeteer/puppeteer @@ -0,0 +1 @@ +Subproject commit 98bb2615adb6815c91efcc59593b49e2ec8c3935 diff --git a/tests/cases/user/puppeteer/test.json b/tests/cases/user/puppeteer/test.json new file mode 100644 index 00000000000..e0d4d26bdca --- /dev/null +++ b/tests/cases/user/puppeteer/test.json @@ -0,0 +1,3 @@ +{ + "types": [] +} From 0c17a2b2a89c05d6f0a5da14706ab029456a0bd1 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 11:28:12 -0700 Subject: [PATCH 085/229] goToDefinition: Reduce duplicate code around createDefinitionInfo (#23473) * goToDefinition: Reduce duplicate code around createDefinitionInfo * Use '[]' instead of 'emptyArray' * Remove comment --- src/services/goToDefinition.ts | 44 ++++++++++------------------------ 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 226fe74ef10..2a1d829e608 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -50,16 +50,7 @@ namespace ts.GoToDefinition { // assignment. This case and others are handled by the following code. if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) { const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); - if (!shorthandSymbol) { - return []; - } - - const shorthandDeclarations = shorthandSymbol.getDeclarations(); - const shorthandSymbolKind = SymbolDisplay.getSymbolKind(typeChecker, shorthandSymbol, node); - const shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol); - const shorthandContainerName = typeChecker.symbolToString(symbol.parent, node); - return map(shorthandDeclarations, - declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName)); + return shorthandSymbol ? shorthandSymbol.declarations.map(decl => createDefinitionInfo(decl, typeChecker, shorthandSymbol, node)) : []; } // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the @@ -191,8 +182,7 @@ namespace ts.GoToDefinition { } function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo[] { - const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, symbol, node); - return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(symbol.declarations, declaration => createDefinitionInfo(declaration, symbolKind, symbolName, containerName)); + return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(symbol.declarations, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node)); function getConstructSignatureDefinition(): DefinitionInfo[] | undefined { // Applicable only if we are in a new expression, or we are on a constructor declaration @@ -215,7 +205,7 @@ namespace ts.GoToDefinition { } const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isSignatureDeclaration); return declarations.length - ? [createDefinitionInfo(find(declarations, d => !!(d).body) || last(declarations), symbolKind, symbolName, containerName)] + ? [createDefinitionInfo(find(declarations, d => !!(d).body) || last(declarations), typeChecker, symbol, node)] : undefined; } } @@ -234,12 +224,16 @@ namespace ts.GoToDefinition { } /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */ - function createDefinitionInfo(node: Declaration, symbolKind: ScriptElementKind, symbolName: string, containerName: string): DefinitionInfo { - return createDefinitionInfoFromName(getNameOfDeclaration(node) || node, symbolKind, symbolName, containerName); + function createDefinitionInfo(declaration: Declaration, checker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo { + const symbolName = checker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol + const symbolKind = SymbolDisplay.getSymbolKind(checker, symbol, node); + const containerName = symbol.parent ? checker.symbolToString(symbol.parent, node) : ""; + return createDefinitionInfoFromName(declaration, symbolKind, symbolName, containerName); } /** Creates a DefinitionInfo directly from the name of a declaration. */ - function createDefinitionInfoFromName(name: Node, symbolKind: ScriptElementKind, symbolName: string, containerName: string): DefinitionInfo { + function createDefinitionInfoFromName(declaration: Declaration, symbolKind: ScriptElementKind, symbolName: string, containerName: string): DefinitionInfo { + const name = getNameOfDeclaration(declaration) || declaration; const sourceFile = name.getSourceFile(); return { fileName: sourceFile.fileName, @@ -251,26 +245,12 @@ namespace ts.GoToDefinition { }; } - function getSymbolInfo(typeChecker: TypeChecker, symbol: Symbol, node: Node) { - return { - symbolName: typeChecker.symbolToString(symbol), // Do not get scoped name, just the name of the symbol - symbolKind: SymbolDisplay.getSymbolKind(typeChecker, symbol, node), - containerName: symbol.parent ? typeChecker.symbolToString(symbol.parent, node) : "" - }; - } - function createDefinitionFromSignatureDeclaration(typeChecker: TypeChecker, decl: SignatureDeclaration): DefinitionInfo { - const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, decl.symbol, decl); - return createDefinitionInfo(decl, symbolKind, symbolName, containerName); + return createDefinitionInfo(decl, typeChecker, decl.symbol, decl); } export function findReferenceInPosition(refs: ReadonlyArray, pos: number): FileReference | undefined { - for (const ref of refs) { - if (ref.pos <= pos && pos <= ref.end) { - return ref; - } - } - return undefined; + return find(refs, ref => ref.pos <= pos && pos <= ref.end); } function getDefinitionInfoForFileReference(name: string, targetFileName: string): DefinitionInfo { From f6510bd6b9619d9c196d4de97dd23aeb658fc6a2 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 11:53:41 -0700 Subject: [PATCH 086/229] goToDefinition: Remove isSignatureDeclaration, use isFunctionLike (#23475) --- src/services/goToDefinition.ts | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 2a1d829e608..f97a8338b05 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -203,26 +203,13 @@ namespace ts.GoToDefinition { if (!signatureDeclarations) { return undefined; } - const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isSignatureDeclaration); + const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isFunctionLike); return declarations.length ? [createDefinitionInfo(find(declarations, d => !!(d).body) || last(declarations), typeChecker, symbol, node)] : undefined; } } - function isSignatureDeclaration(node: Node): boolean { - switch (node.kind) { - case SyntaxKind.Constructor: - case SyntaxKind.ConstructSignature: - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - return true; - default: - return false; - } - } - /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */ function createDefinitionInfo(declaration: Declaration, checker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo { const symbolName = checker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol @@ -278,13 +265,7 @@ namespace ts.GoToDefinition { function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): SignatureDeclaration | undefined { const callLike = getAncestorCallLikeExpression(node); const signature = callLike && typeChecker.getResolvedSignature(callLike); - if (signature) { - const decl = signature.declaration; - if (decl && isSignatureDeclaration(decl)) { - return decl; - } - } // Don't go to a function type, go to the value having that type. - return undefined; + return tryCast(signature && signature.declaration, (d): d is SignatureDeclaration => isFunctionLike(d) && !isFunctionTypeNode(d)); } } From 56d83f95723d6dc238da7a7e629a8e7f96b4d3ce Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 12:41:39 -0700 Subject: [PATCH 087/229] Rename `pushTypePart` to `pushSymbolKind` (#23481) --- src/services/symbolDisplay.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 4693a5089f1..66367905af8 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -178,7 +178,7 @@ namespace ts.SymbolDisplay { } else if (symbolFlags & SymbolFlags.Alias) { symbolKind = ScriptElementKind.alias; - pushTypePart(symbolKind); + pushSymbolKind(symbolKind); displayParts.push(spacePart()); if (useConstructSignatures) { displayParts.push(keywordPart(SyntaxKind.NewKeyword)); @@ -258,7 +258,7 @@ namespace ts.SymbolDisplay { // Special case for class expressions because we would like to indicate that // the class name is local to the class body (similar to function expression) // (local class) class - pushTypePart(ScriptElementKind.localClassElement); + pushSymbolKind(ScriptElementKind.localClassElement); } else { // Class declaration has name which is not local. @@ -531,7 +531,7 @@ namespace ts.SymbolDisplay { function addAliasPrefixIfNecessary() { if (alias) { - pushTypePart(ScriptElementKind.alias); + pushSymbolKind(ScriptElementKind.alias); displayParts.push(spacePart()); } } @@ -554,7 +554,7 @@ namespace ts.SymbolDisplay { function addPrefixForAnyFunctionOrVar(symbol: Symbol, symbolKind: string) { prefixNextMeaning(); if (symbolKind) { - pushTypePart(symbolKind); + pushSymbolKind(symbolKind); if (symbol && !some(symbol.declarations, d => isArrowFunction(d) || (isFunctionExpression(d) || isClassExpression(d)) && !d.name)) { displayParts.push(spacePart()); addFullSymbolName(symbol); @@ -562,7 +562,7 @@ namespace ts.SymbolDisplay { } } - function pushTypePart(symbolKind: string) { + function pushSymbolKind(symbolKind: string) { switch (symbolKind) { case ScriptElementKind.variableElement: case ScriptElementKind.functionElement: From b00e37060501fad1d7e7b3c4387128b61d8372ce Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 12:42:23 -0700 Subject: [PATCH 088/229] Add '?' in quick info for optional properties/methods (#23480) --- src/services/symbolDisplay.ts | 4 ++++ tests/cases/fourslash/findAllRefsForObjectSpread.ts | 4 ++-- .../findAllRefsObjectBindingElementPropertyName10.ts | 2 +- .../quickInfoForObjectBindingElementPropertyName03.ts | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 66367905af8..7431393df87 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -549,6 +549,10 @@ namespace ts.SymbolDisplay { const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined, SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind); addRange(displayParts, fullSymbolDisplayParts); + + if (symbol.flags & SymbolFlags.Optional) { + displayParts.push(punctuationPart(SyntaxKind.QuestionToken)); + } } function addPrefixForAnyFunctionOrVar(symbol: Symbol, symbolKind: string) { diff --git a/tests/cases/fourslash/findAllRefsForObjectSpread.ts b/tests/cases/fourslash/findAllRefsForObjectSpread.ts index 970806922ed..c6f111672c8 100644 --- a/tests/cases/fourslash/findAllRefsForObjectSpread.ts +++ b/tests/cases/fourslash/findAllRefsForObjectSpread.ts @@ -12,12 +12,12 @@ const [r0, r1, r2, r3] = ranges; // members of spread types only refer to themselves and the resulting property verify.referenceGroups(r0, [{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] }]); -verify.referenceGroups(r1, [{ definition: "(property) A2.a: number", ranges: [r1, r2] }]); +verify.referenceGroups(r1, [{ definition: "(property) A2.a?: number", ranges: [r1, r2] }]); // but the resulting property refers to everything verify.referenceGroups(r2, [ { definition: "(property) A1.a: string", ranges: [r0, r2, r3] }, - { definition: "(property) A2.a: number", ranges: [r1] }, + { definition: "(property) A2.a?: number", ranges: [r1] }, ]); verify.referenceGroups(r3, [{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] }]); diff --git a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts index 1c79d326dbc..500ca7fe3cf 100644 --- a/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts +++ b/tests/cases/fourslash/findAllRefsObjectBindingElementPropertyName10.ts @@ -8,4 +8,4 @@ ////function f ({ [|next|]: { [|next|]: x} }: Recursive) { ////} -verify.singleReferenceGroup("(property) Recursive.next: Recursive"); +verify.singleReferenceGroup("(property) Recursive.next?: Recursive"); diff --git a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName03.ts b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName03.ts index c29a7265eab..9378c99126c 100644 --- a/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName03.ts +++ b/tests/cases/fourslash/quickInfoForObjectBindingElementPropertyName03.ts @@ -9,5 +9,5 @@ ////} for (const marker of test.markerNames()) { - verify.quickInfoAt(marker, "(property) Recursive.next: Recursive"); + verify.quickInfoAt(marker, "(property) Recursive.next?: Recursive"); } \ No newline at end of file From c645f1753f588605aec5cc938f59fbdccdcd98f0 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 17 Apr 2018 15:42:31 -0400 Subject: [PATCH 089/229] Update configurePrerelease to not utilize ts internals (#23476) * update configure nightly to not utilize ts internals * Nightly -> Prerelease * Remove alias --- Gulpfile.ts | 17 ++++----- Jakefile.js | 2 +- scripts/configurePrerelease.ts | 36 ++++++++++--------- .../TypeScript-Node-Starter | 2 +- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/Gulpfile.ts b/Gulpfile.ts index 26622f36fe8..7f7e525564c 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -215,8 +215,8 @@ for (const i in libraryTargets) { .pipe(gulp.dest("."))); } -const configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js"); -const configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts"); +const configurePreleleaseJs = path.join(scriptsDirectory, "configurePrerelease.js"); +const configurePreleleaseTs = path.join(scriptsDirectory, "configurePrerelease.ts"); const packageJson = "package.json"; const versionFile = path.join(compilerDirectory, "core.ts"); @@ -301,24 +301,25 @@ function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): ts return copy; } -gulp.task(configureNightlyJs, /*help*/ false, [], () => { +gulp.task(configurePreleleaseJs, /*help*/ false, [], () => { const settings: tsc.Settings = { declaration: false, removeComments: true, noResolve: false, stripInternal: false, + module: "commonjs" }; - return gulp.src(configureNightlyTs) + return gulp.src(configurePreleleaseTs) .pipe(sourcemaps.init()) .pipe(tsc(settings)) - .pipe(sourcemaps.write(path.dirname(configureNightlyJs))) - .pipe(gulp.dest(path.dirname(configureNightlyJs))); + .pipe(sourcemaps.write(".")) + .pipe(gulp.dest("./scripts")); }); // Nightly management tasks -gulp.task("configure-nightly", "Runs scripts/configureNightly.ts to prepare a build for nightly publishing", [configureNightlyJs], (done) => { - exec(host, [configureNightlyJs, packageJson, versionFile], done, done); +gulp.task("configure-nightly", "Runs scripts/configurePrerelease.ts to prepare a build for nightly publishing", [configurePreleleaseJs], (done) => { + exec(host, [configurePreleleaseJs, "dev", packageJson, versionFile], done, done); }); gulp.task("publish-nightly", "Runs `npm publish --tag next` to create a new nightly build on npm", ["LKG"], () => { return runSequence("clean", "useDebugMode", "runtests-parallel", (done) => { diff --git a/Jakefile.js b/Jakefile.js index bda270b0b4c..3eb8736445b 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -491,7 +491,7 @@ compileFile(/*outfile*/configurePrereleaseJs, /*prereqs*/[configurePrereleaseTs], /*prefixes*/[], /*useBuiltCompiler*/ false, - { noOutFile: false, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false }); + { noOutFile: true, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false }); task("setDebugMode", function () { useDebugMode = true; diff --git a/scripts/configurePrerelease.ts b/scripts/configurePrerelease.ts index d17ddb963b1..da1984c13e0 100644 --- a/scripts/configurePrerelease.ts +++ b/scripts/configurePrerelease.ts @@ -1,4 +1,9 @@ -/// +/// +import { normalize } from "path"; +import assert = require("assert"); +import { readFileSync, writeFileSync } from "fs"; +const args = process.argv.slice(2); + /** * A minimal description for a parsed package.json object. @@ -10,28 +15,27 @@ interface PackageJson { } function main(): void { - const sys = ts.sys; - if (sys.args.length < 3) { - sys.write("Usage:" + sys.newLine) - sys.write("\tnode configureNightly.js " + sys.newLine); + if (args.length < 3) { + console.log("Usage:"); + console.log("\tnode configureNightly.js "); return; } - const tag = sys.args[0]; + const tag = args[0]; if (tag !== "dev" && tag !== "insiders") { throw new Error(`Unexpected tag name '${tag}'.`); } // Acquire the version from the package.json file and modify it appropriately. - const packageJsonFilePath = ts.normalizePath(sys.args[1]); - const packageJsonValue: PackageJson = JSON.parse(sys.readFile(packageJsonFilePath)); + const packageJsonFilePath = normalize(args[1]); + const packageJsonValue: PackageJson = JSON.parse(readFileSync(packageJsonFilePath).toString()); const { majorMinor, patch } = parsePackageJsonVersion(packageJsonValue.version); const prereleasePatch = getPrereleasePatch(tag, patch); // Acquire and modify the source file that exposes the version string. - const tsFilePath = ts.normalizePath(sys.args[2]); - const tsFileContents = ts.sys.readFile(tsFilePath); + const tsFilePath = normalize(args[2]); + const tsFileContents = readFileSync(tsFilePath).toString(); const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, prereleasePatch); // Ensure we are actually changing something - the user probably wants to know that the update failed. @@ -44,20 +48,20 @@ function main(): void { // Finally write the changes to disk. // Modify the package.json structure packageJsonValue.version = `${majorMinor}.${prereleasePatch}`; - sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4)) - sys.writeFile(tsFilePath, modifiedTsFileContents); + writeFileSync(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4)) + writeFileSync(tsFilePath, modifiedTsFileContents); } function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: string, patch: string, nightlyPatch: string): string { const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/; const majorMinorMatch = majorMinorRgx.exec(tsFileContents); - ts.Debug.assert(majorMinorMatch !== null, "", () => `The file seems to no longer have a string matching '${majorMinorRgx}'.`); + assert(majorMinorMatch !== null, `The file seems to no longer have a string matching '${majorMinorRgx}'.`); const parsedMajorMinor = majorMinorMatch[1]; - ts.Debug.assert(parsedMajorMinor === majorMinor, "versionMajorMinor does not match.", () => `${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`); + assert(parsedMajorMinor === majorMinor, `versionMajorMinor does not match. ${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`); const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)(-dev)?`;/; const patchMatch = versionRgx.exec(tsFileContents); - ts.Debug.assert(patchMatch !== null, "The file seems to no longer have a string matching", () => versionRgx.toString()); + assert(patchMatch !== null, "The file seems to no longer have a string matching " + versionRgx.toString()); const parsedPatch = patchMatch[1]; if (parsedPatch !== patch) { throw new Error(`patch does not match. ${tsFilePath}: '${parsedPatch}; package.json: '${patch}'`); @@ -69,7 +73,7 @@ function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: st function parsePackageJsonVersion(versionString: string): { majorMinor: string, patch: string } { const versionRgx = /(\d+\.\d+)\.(\d+)($|\-)/; const match = versionString.match(versionRgx); - ts.Debug.assert(match !== null, "package.json 'version' should match", () => versionRgx.toString()); + assert(match !== null, "package.json 'version' should match " + versionRgx.toString()); return { majorMinor: match[1], patch: match[2] }; } diff --git a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter index 6b9706810b5..40bdb4eadab 160000 --- a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter +++ b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter @@ -1 +1 @@ -Subproject commit 6b9706810b55af326a93b9aa59cb17815a30bb32 +Subproject commit 40bdb4eadabc9fbed7d83e3f26817a931c0763b6 From d1fde3786c4a1509b5172540bbaac02c05c22387 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 14:07:59 -0700 Subject: [PATCH 090/229] Symbol kind for a method on a mapped type should still be 'method' (#23478) --- src/services/symbolDisplay.ts | 9 +++++++++ .../{server => }/quickInfoMappedSpreadTypes.ts | 2 +- tests/cases/fourslash/quickInfoMappedType.ts | 11 +++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) rename tests/cases/fourslash/{server => }/quickInfoMappedSpreadTypes.ts (89%) create mode 100644 tests/cases/fourslash/quickInfoMappedType.ts diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 7431393df87..f79c048efad 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -26,6 +26,15 @@ namespace ts.SymbolDisplay { } function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: TypeChecker, symbol: Symbol, location: Node): ScriptElementKind { + const roots = typeChecker.getRootSymbols(symbol); + // If this is a method from a mapped type, leave as a method so long as it still has a call signature. + if (roots.length === 1 + && first(roots).flags & SymbolFlags.Method + // Ensure the mapped version is still a method, as opposed to `{ [K in keyof I]: number }`. + && typeChecker.getTypeOfSymbolAtLocation(symbol, location).getNonNullableType().getCallSignatures().length !== 0) { + return ScriptElementKind.memberFunctionElement; + } + if (typeChecker.isUndefinedSymbol(symbol)) { return ScriptElementKind.variableElement; } diff --git a/tests/cases/fourslash/server/quickInfoMappedSpreadTypes.ts b/tests/cases/fourslash/quickInfoMappedSpreadTypes.ts similarity index 89% rename from tests/cases/fourslash/server/quickInfoMappedSpreadTypes.ts rename to tests/cases/fourslash/quickInfoMappedSpreadTypes.ts index 2a0c1668763..c1e34f49bfc 100644 --- a/tests/cases/fourslash/server/quickInfoMappedSpreadTypes.ts +++ b/tests/cases/fourslash/quickInfoMappedSpreadTypes.ts @@ -1,4 +1,4 @@ -/// +/// ////interface Foo { //// /** Doc */ diff --git a/tests/cases/fourslash/quickInfoMappedType.ts b/tests/cases/fourslash/quickInfoMappedType.ts new file mode 100644 index 00000000000..c4afb444155 --- /dev/null +++ b/tests/cases/fourslash/quickInfoMappedType.ts @@ -0,0 +1,11 @@ +/// + +////interface I { m(): void; } +////declare const o: { [K in keyof I]: number }; +////o.m/*0*/; +//// +////declare const p: { [K in keyof I]: I[K] }; +////p.m/*1*/; + +verify.quickInfoAt("0", "(property) m: number"); +verify.quickInfoAt("1", "(method) m(): void"); From 4bfb1a3aa14972e536247feac316546d9965e790 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 17 Apr 2018 14:09:42 -0700 Subject: [PATCH 091/229] Avoid breaking change by introducing overloads for 'createTaggedTemplate'/'updateTaggedTemplate'. --- src/compiler/factory.ts | 27 ++++++++++++++++++++------- src/compiler/parser.ts | 1 - 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 7dd7216725a..e3191930c0e 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1032,19 +1032,32 @@ namespace ts { : node; } - export function createTaggedTemplate(tag: Expression, typeArguments: NodeArray, template: TemplateLiteral) { + export function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + export function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray, template: TemplateLiteral): TaggedTemplateExpression; + /** @internal */ + export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral, template?: TemplateLiteral): TaggedTemplateExpression; + export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral, template?: TemplateLiteral) { const node = createSynthesizedNode(SyntaxKind.TaggedTemplateExpression); node.tag = parenthesizeForAccess(tag); - node.typeArguments = typeArguments; - node.template = template; + if (template) { + node.typeArguments = asNodeArray(typeArgumentsOrTemplate as ReadonlyArray); + node.template = template!; + } + else { + node.typeArguments = undefined; + node.template = typeArgumentsOrTemplate as TemplateLiteral; + } return node; } - export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: NodeArray, template: TemplateLiteral) { + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray, template: TemplateLiteral): TaggedTemplateExpression; + export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArgumentsOrTemplate: ReadonlyArray | TemplateLiteral, template?: TemplateLiteral) { return node.tag !== tag - || node.typeArguments !== typeArguments - || node.template !== template - ? updateNode(createTaggedTemplate(tag, typeArguments, template), node) + || (template + ? node.typeArguments !== typeArgumentsOrTemplate || node.template !== template + : node.typeArguments !== undefined || node.template !== typeArgumentsOrTemplate) + ? updateNode(createTaggedTemplate(tag, typeArgumentsOrTemplate, template), node) : node; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index f5dd8fa764d..4cf4c6e4c67 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4370,7 +4370,6 @@ namespace ts { return expression; } - } function isTemplateStartOfTaggedTemplate() { From 78e98c37841b17ce7d5c540050cc1e4925458d1c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 17 Apr 2018 14:15:36 -0700 Subject: [PATCH 092/229] Accepted baselines. --- tests/baselines/reference/api/tsserverlibrary.d.ts | 6 ++++-- tests/baselines/reference/api/typescript.d.ts | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a250dcf6961..06ecede8c88 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3517,8 +3517,10 @@ declare namespace ts { function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray): CallExpression; function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; - function createTaggedTemplate(tag: Expression, typeArguments: NodeArray, template: TemplateLiteral): TaggedTemplateExpression; - function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: NodeArray, template: TemplateLiteral): TaggedTemplateExpression; + function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray, template: TemplateLiteral): TaggedTemplateExpression; + function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray, template: TemplateLiteral): TaggedTemplateExpression; function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; function createParen(expression: Expression): ParenthesizedExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 4e15b26a13d..9d99813cfe1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3517,8 +3517,10 @@ declare namespace ts { function updateCall(node: CallExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray): CallExpression; function createNew(expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; function updateNew(node: NewExpression, expression: Expression, typeArguments: ReadonlyArray | undefined, argumentsArray: ReadonlyArray | undefined): NewExpression; - function createTaggedTemplate(tag: Expression, typeArguments: NodeArray, template: TemplateLiteral): TaggedTemplateExpression; - function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: NodeArray, template: TemplateLiteral): TaggedTemplateExpression; + function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray, template: TemplateLiteral): TaggedTemplateExpression; + function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression; + function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray, template: TemplateLiteral): TaggedTemplateExpression; function createTypeAssertion(type: TypeNode, expression: Expression): TypeAssertion; function updateTypeAssertion(node: TypeAssertion, type: TypeNode, expression: Expression): TypeAssertion; function createParen(expression: Expression): ParenthesizedExpression; From d64f2483e4c8838ff7bc46fa106c69a05901769d Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 17 Apr 2018 14:17:15 -0700 Subject: [PATCH 093/229] Update to respond to PR feedback --- src/compiler/core.ts | 2 +- src/compiler/resolutionCache.ts | 20 +++-- src/server/project.ts | 82 ++++++++----------- src/server/scriptInfo.ts | 10 +-- .../reference/api/tsserverlibrary.d.ts | 8 +- 5 files changed, 57 insertions(+), 65 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index b427c689c96..0e53ae2946d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2988,7 +2988,7 @@ namespace ts { /** Remove the *first* occurrence of `item` from the array. */ export function unorderedRemoveItem(array: T[], item: T) { - unorderedRemoveFirstItemWhere(array, element => element === item); + return unorderedRemoveFirstItemWhere(array, element => element === item); } /** Remove the *first* element satisfying `predicate`. */ diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 2cd39068de1..35e056546c0 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -10,7 +10,7 @@ namespace ts { invalidateResolutionOfFile(filePath: Path): void; removeResolutionsOfFile(filePath: Path): void; - setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map): void; + setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map>): void; createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution; startCachingPerDirectoryResolution(): void; @@ -75,7 +75,7 @@ namespace ts { export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string, logChangesWhenResolvingModule: boolean): ResolutionCache { let filesWithChangedSetOfUnresolvedImports: Path[] | undefined; let filesWithInvalidatedResolutions: Map | undefined; - let filesWithInvalidatedNonRelativeUnresolvedImports: Map | undefined; + let filesWithInvalidatedNonRelativeUnresolvedImports: Map> | undefined; let allFilesHaveInvalidatedResolution = false; const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory()); @@ -168,6 +168,16 @@ namespace ts { return collected; } + function isFileWithInvalidatedNonRelativeUnresolvedImports(path: Path) { + if (!filesWithInvalidatedNonRelativeUnresolvedImports) { + return false; + } + + // Invalidated if file has unresolved imports + const value = filesWithInvalidatedNonRelativeUnresolvedImports.get(path); + return value && !!value.length; + } + function createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution { if (allFilesHaveInvalidatedResolution || forceAllFilesAsInvalidated) { // Any file asked would have invalidated resolution @@ -177,7 +187,7 @@ namespace ts { const collected = filesWithInvalidatedResolutions; filesWithInvalidatedResolutions = undefined; return path => (collected && collected.has(path)) || - (filesWithInvalidatedNonRelativeUnresolvedImports && filesWithInvalidatedNonRelativeUnresolvedImports.has(path)); + isFileWithInvalidatedNonRelativeUnresolvedImports(path); } function clearPerDirectoryResolutions() { @@ -242,7 +252,7 @@ namespace ts { const resolvedModules: R[] = []; const compilerOptions = resolutionHost.getCompilationSettings(); - const hasInvalidatedNonRelativeUnresolvedImport = logChanges && filesWithInvalidatedNonRelativeUnresolvedImports && filesWithInvalidatedNonRelativeUnresolvedImports.has(path); + const hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path); const seenNamesInFile = createMap(); for (const name of names) { let resolution = resolutionsInFile.get(name); @@ -584,7 +594,7 @@ namespace ts { ); } - function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: Map) { + function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: Map>) { Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined); filesWithInvalidatedNonRelativeUnresolvedImports = filesMap; } diff --git a/src/server/project.ts b/src/server/project.ts index 67469cc69d8..653f2943d0a 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -96,15 +96,10 @@ namespace ts.server { */ cachedUnresolvedImportsPerFile = createMap>(); - /** - * This is the set that has entry to true if file doesnt contain any unresolved import - */ - private filesWithNoUnresolvedImports = createMap(); - /*@internal*/ lastCachedUnresolvedImportsList: SortedReadonlyArray; /*@internal*/ - hasMoreOrLessScriptInfos = false; + private hasMoreOrLessFiles = false; private lastFileExceededProgramSize: string | undefined; @@ -136,10 +131,10 @@ namespace ts.server { */ private lastReportedVersion = 0; /** - * Current project structure version. + * Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one) * This property is changed in 'updateGraph' based on the set of files in program */ - private projectStructureVersion = 0; + private projectProgramVersion = 0; /** * Current version of the project state. It is changed when: * - new root file was added/removed @@ -566,7 +561,6 @@ namespace ts.server { this.resolutionCache.clear(); this.resolutionCache = undefined; this.cachedUnresolvedImportsPerFile = undefined; - this.filesWithNoUnresolvedImports = undefined; this.directoryStructureHost = undefined; // Clean up file watchers waiting for missing files @@ -727,7 +721,6 @@ namespace ts.server { else { this.resolutionCache.invalidateResolutionOfFile(info.path); } - this.filesWithNoUnresolvedImports.delete(info.path); this.cachedUnresolvedImportsPerFile.delete(info.path); if (detachFromProject) { @@ -749,19 +742,11 @@ namespace ts.server { } /* @internal */ - private extractUnresolvedImportsFromSourceFile(file: SourceFile, result: string[] | undefined, ambientModules: string[]): string[] | undefined { - // No unresolve imports in this file - if (this.filesWithNoUnresolvedImports.has(file.path)) { - return result; - } - + private extractUnresolvedImportsFromSourceFile(file: SourceFile, ambientModules: string[]): ReadonlyArray { const cached = this.cachedUnresolvedImportsPerFile.get(file.path); if (cached) { - // found cached result - use it and return - for (const f of cached) { - (result || (result = [])).push(f); - } - return result; + // found cached result, return + return cached; } let unresolvedImports: string[] | undefined; if (file.resolvedModules) { @@ -779,23 +764,23 @@ namespace ts.server { trimmed = trimmed.substr(0, i); } (unresolvedImports || (unresolvedImports = [])).push(trimmed); - (result || (result = [])).push(trimmed); } }); } - if (unresolvedImports) { - this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports); - } - else { - this.filesWithNoUnresolvedImports.set(file.path, true); - } - return result; + + this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray); + return unresolvedImports || emptyArray; function isAmbientlyDeclaredModule(name: string) { return ambientModules.some(m => m === name); } } + /* @internal */ + setHasMoreOrLessFiles() { + this.hasMoreOrLessFiles = true; + } + /** * Updates set of files that contribute to this project * @returns: true if set of files in the project stays the same and false - otherwise. @@ -803,16 +788,15 @@ namespace ts.server { updateGraph(): boolean { this.resolutionCache.startRecordingFilesWithChangedResolutions(); - const hasChanges = this.updateGraphWorker(); - const hasMoreOrLessScriptInfos = this.hasMoreOrLessScriptInfos; - this.hasMoreOrLessScriptInfos = false; + const hasNewProgram = this.updateGraphWorker(); + const hasMoreOrLessFiles = this.hasMoreOrLessFiles; + this.hasMoreOrLessFiles = false; const changedFiles: ReadonlyArray = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || emptyArray; for (const file of changedFiles) { // delete cached information for changed files this.cachedUnresolvedImportsPerFile.delete(file); - this.filesWithNoUnresolvedImports.delete(file); } // update builder only if language service is enabled @@ -824,25 +808,28 @@ namespace ts.server { // 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files // (can reuse cached imports for files that were not changed) // 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch - if (hasChanges || changedFiles.length) { + if (hasNewProgram || changedFiles.length) { let result: string[] | undefined; const ambientModules = this.program.getTypeChecker().getAmbientModules().map(mod => stripQuotes(mod.getName())); for (const sourceFile of this.program.getSourceFiles()) { - result = this.extractUnresolvedImportsFromSourceFile(sourceFile, result, ambientModules); + const unResolved = this.extractUnresolvedImportsFromSourceFile(sourceFile, ambientModules); + if (unResolved !== emptyArray) { + (result || (result = [])).push(...unResolved); + } } this.lastCachedUnresolvedImportsList = result ? toDeduplicatedSortedArray(result) : emptyArray; } - this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasMoreOrLessScriptInfos); + this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasMoreOrLessFiles); } else { this.lastCachedUnresolvedImportsList = undefined; } - if (hasChanges) { - this.projectStructureVersion++; + if (hasNewProgram) { + this.projectProgramVersion++; } - return !hasChanges; + return !hasNewProgram; } /*@internal*/ @@ -878,9 +865,9 @@ namespace ts.server { // bump up the version if // - oldProgram is not set - this is a first time updateGraph is called // - newProgram is different from the old program and structure of the old program was not reused. - const hasChanges = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely))); + const hasNewProgram = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely))); this.hasChangedAutomaticTypeDirectiveNames = false; - if (hasChanges) { + if (hasNewProgram) { if (oldProgram) { for (const f of oldProgram.getSourceFiles()) { if (this.program.getSourceFileByPath(f.path)) { @@ -918,8 +905,8 @@ namespace ts.server { removed => this.detachScriptInfoFromProject(removed) ); const elapsed = timestamp() - start; - this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasChanges} Elapsed: ${elapsed}ms`); - return hasChanges; + this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasNewProgram} Elapsed: ${elapsed}ms`); + return hasNewProgram; } private detachScriptInfoFromProject(uncheckedFileName: string) { @@ -993,7 +980,6 @@ namespace ts.server { if (changesAffectModuleResolution(oldOptions, compilerOptions)) { // reset cached unresolved imports if changes in compiler options affected module resolution this.cachedUnresolvedImportsPerFile.clear(); - this.filesWithNoUnresolvedImports.clear(); this.lastCachedUnresolvedImportsList = undefined; this.resolutionCache.clear(); } @@ -1007,7 +993,7 @@ namespace ts.server { const info: protocol.ProjectVersionInfo = { projectName: this.getProjectName(), - version: this.projectStructureVersion, + version: this.projectProgramVersion, isInferred: this.projectKind === ProjectKind.Inferred, options: this.getCompilationSettings(), languageServiceDisabled: !this.languageServiceEnabled, @@ -1018,7 +1004,7 @@ namespace ts.server { // check if requested version is the same that we have reported last time if (this.lastReportedFileNames && lastKnownVersion === this.lastReportedVersion) { // if current structure version is the same - return info without any changes - if (this.projectStructureVersion === this.lastReportedVersion && !updatedFileNames) { + if (this.projectProgramVersion === this.lastReportedVersion && !updatedFileNames) { return { info, projectErrors: this.getGlobalProjectErrors() }; } // compute and return the difference @@ -1041,7 +1027,7 @@ namespace ts.server { } }); this.lastReportedFileNames = currentFiles; - this.lastReportedVersion = this.projectStructureVersion; + this.lastReportedVersion = this.projectProgramVersion; return { info, changes: { added, removed, updated }, projectErrors: this.getGlobalProjectErrors() }; } else { @@ -1050,7 +1036,7 @@ namespace ts.server { const externalFiles = this.getExternalFiles().map(f => toNormalizedPath(f)); const allFiles = projectFileNames.concat(externalFiles); this.lastReportedFileNames = arrayToSet(allFiles); - this.lastReportedVersion = this.projectStructureVersion; + this.lastReportedVersion = this.projectProgramVersion; return { info, files: allFiles, projectErrors: this.getGlobalProjectErrors() }; } } diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 074fde298aa..cc4ebd519e5 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -304,7 +304,7 @@ namespace ts.server { const isNew = !this.isAttached(project); if (isNew) { this.containingProjects.push(project); - project.hasMoreOrLessScriptInfos = true; + project.setHasMoreOrLessFiles(); if (!project.getCompilerOptions().preserveSymlinks) { this.ensureRealPath(); } @@ -329,23 +329,23 @@ namespace ts.server { return; case 1: if (this.containingProjects[0] === project) { - project.hasMoreOrLessScriptInfos = true; + project.setHasMoreOrLessFiles(); this.containingProjects.pop(); } break; case 2: if (this.containingProjects[0] === project) { - project.hasMoreOrLessScriptInfos = true; + project.setHasMoreOrLessFiles(); this.containingProjects[0] = this.containingProjects.pop(); } else if (this.containingProjects[1] === project) { - project.hasMoreOrLessScriptInfos = true; + project.setHasMoreOrLessFiles(); this.containingProjects.pop(); } break; default: if (unorderedRemoveItem(this.containingProjects, project)) { - project.hasMoreOrLessScriptInfos = true; + project.setHasMoreOrLessFiles(); } break; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 53c23b1d382..a81f1c66c22 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -7643,10 +7643,6 @@ declare namespace ts.server { private externalFiles; private missingFilesMap; private plugins; - /** - * This is the set that has entry to true if file doesnt contain any unresolved import - */ - private filesWithNoUnresolvedImports; private lastFileExceededProgramSize; protected languageService: LanguageService; languageServiceEnabled: boolean; @@ -7666,10 +7662,10 @@ declare namespace ts.server { */ private lastReportedVersion; /** - * Current project structure version. + * Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one) * This property is changed in 'updateGraph' based on the set of files in program */ - private projectStructureVersion; + private projectProgramVersion; /** * Current version of the project state. It is changed when: * - new root file was added/removed From 391c0565d7c8138b2d9b3541faef648dfa9debd9 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 17 Apr 2018 17:19:42 -0400 Subject: [PATCH 094/229] Use ts-check instead of ts-node to avoid transpilation overhead on gulp startup (#23486) --- Gulpfile.ts => Gulpfile.js | 223 +++++++++++++++++++------------------ package.json | 1 - 2 files changed, 113 insertions(+), 111 deletions(-) rename Gulpfile.ts => Gulpfile.js (87%) diff --git a/Gulpfile.ts b/Gulpfile.js similarity index 87% rename from Gulpfile.ts rename to Gulpfile.js index 7f7e525564c..afa7e775dcd 100644 --- a/Gulpfile.ts +++ b/Gulpfile.js @@ -1,35 +1,27 @@ /// -import * as cp from "child_process"; -import * as path from "path"; -import * as fs from "fs"; -import child_process = require("child_process"); -import originalGulp = require("gulp"); -import helpMaker = require("gulp-help"); -import runSequence = require("run-sequence"); -import concat = require("gulp-concat"); -import clone = require("gulp-clone"); -import newer = require("gulp-newer"); -import tsc = require("gulp-typescript"); -declare module "gulp-typescript" { - interface Settings { - pretty?: boolean; - newLine?: string; - noImplicitThis?: boolean; - stripInternal?: boolean; - types?: string[]; - } -} -import * as insert from "gulp-insert"; -import * as sourcemaps from "gulp-sourcemaps"; -import Q = require("q"); -import del = require("del"); -import mkdirP = require("mkdirp"); -import minimist = require("minimist"); -import browserify = require("browserify"); -import through2 = require("through2"); -import merge2 = require("merge2"); -import * as os from "os"; -import fold = require("travis-fold"); +// @ts-check +const cp = require("child_process"); +const path = require("path"); +const fs = require("fs"); +const child_process = require("child_process"); +const originalGulp = require("gulp"); +const helpMaker = require("gulp-help"); +const runSequence = require("run-sequence"); +const concat = require("gulp-concat"); +const clone = require("gulp-clone"); +const newer = require("gulp-newer"); +const tsc = require("gulp-typescript"); +const insert = require("gulp-insert"); +const sourcemaps = require("gulp-sourcemaps"); +const Q = require("q"); +const del = require("del"); +const mkdirP = require("mkdirp"); +const minimist = require("minimist"); +const browserify = require("browserify"); +const through2 = require("through2"); +const merge2 = require("merge2"); +const os = require("os"); +const fold = require("travis-fold"); const gulp = helpMaker(originalGulp); Error.stackTraceLimit = 1000; @@ -73,17 +65,26 @@ const cmdLineOptions = minimist(process.argv.slice(2), { }); const noop = () => {}; // tslint:disable-line no-empty -function exec(cmd: string, args: string[], complete: () => void = noop, error: (e: any, status: number) => void = noop) { +/** + * @param {string} cmd + * @param {string[]} args + * @param {() => void} complete + * @param {(e: *, status: number) => void} error + */ +function exec(cmd, args, complete = noop, error = noop) { console.log(`${cmd} ${args.join(" ")}`); // TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition const subshellFlag = isWin ? "/c" : "-c"; const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`]; - const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true } as any); + const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true }); ex.on("exit", (code) => code === 0 ? complete() : error(/*e*/ undefined, code)); ex.on("error", error); } -function possiblyQuote(cmd: string) { +/** + * @param {string} cmd + */ +function possiblyQuote(cmd) { return cmd.indexOf(" ") >= 0 ? `"${cmd}"` : cmd; } @@ -220,7 +221,12 @@ const configurePreleleaseTs = path.join(scriptsDirectory, "configurePrerelease.t const packageJson = "package.json"; const versionFile = path.join(compilerDirectory, "core.ts"); -function needsUpdate(source: string | string[], dest: string | string[]): boolean { +/** + * @param {string | string[]} source + * @param {string | string[]} dest + * @returns {boolean} + */ +function needsUpdate(source, dest) { if (typeof source === "string" && typeof dest === "string") { if (fs.existsSync(dest)) { const {mtime: outTime} = fs.statSync(dest); @@ -283,8 +289,13 @@ function needsUpdate(source: string | string[], dest: string | string[]): boolea return true; } -function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): tsc.Settings { - const copy: tsc.Settings = {}; +/** + * @param {tsc.Settings} base + * @param {boolean=} useBuiltCompiler + * @returns {tsc.Settings} + */ +function getCompilerSettings(base, useBuiltCompiler) { + const copy = /** @type {tsc.Settings} */ ({}); for (const key in base) { copy[key] = base[key]; } @@ -293,16 +304,17 @@ function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): ts } copy.newLine = "lf"; if (useBuiltCompiler === true) { - copy.typescript = require("./built/local/typescript.js"); + copy.typescript = /** @type {*} */ (require("./built/local/typescript.js")); } else if (useBuiltCompiler === false) { - copy.typescript = require("./lib/typescript.js"); + copy.typescript = /** @type {*} */ (require("./lib/typescript.js")); } return copy; } gulp.task(configurePreleleaseJs, /*help*/ false, [], () => { - const settings: tsc.Settings = { + /** @type {tsc.Settings} */ + const settings = { declaration: false, removeComments: true, noResolve: false, @@ -332,7 +344,8 @@ const importDefinitelyTypedTestsJs = path.join(importDefinitelyTypedTestsDirecto const importDefinitelyTypedTestsTs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.ts"); gulp.task(importDefinitelyTypedTestsJs, /*help*/ false, [], () => { - const settings: tsc.Settings = getCompilerSettings({ + /** @type {tsc.Settings} */ + const settings = getCompilerSettings({ declaration: false, removeComments: true, noResolve: false, @@ -394,7 +407,8 @@ const generateLocalizedDiagnosticMessagesJs = path.join(scriptsDirectory, "gener const generateLocalizedDiagnosticMessagesTs = path.join(scriptsDirectory, "generateLocalizedDiagnosticMessages.ts"); gulp.task(generateLocalizedDiagnosticMessagesJs, /*help*/ false, [], () => { - const settings: tsc.Settings = getCompilerSettings({ + /** @type {tsc.Settings} */ + const settings = getCompilerSettings({ target: "es5", declaration: false, removeComments: true, @@ -425,8 +439,12 @@ const nodePackageFile = path.join(builtLocalDirectory, "typescript.js"); const nodeDefinitionsFile = path.join(builtLocalDirectory, "typescript.d.ts"); const nodeStandaloneDefinitionsFile = path.join(builtLocalDirectory, "typescript_standalone.d.ts"); -let copyrightContent: string; -function prependCopyright(outputCopyright: boolean = !useDebugMode) { +/** @type {string} */ +let copyrightContent; +/** + * @param {boolean} outputCopyright + */ +function prependCopyright(outputCopyright = !useDebugMode) { return insert.prepend(outputCopyright ? (copyrightContent || (copyrightContent = fs.readFileSync(copyright).toString())) : ""); } @@ -518,9 +536,10 @@ const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverli gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (done) => { const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ true)); - const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src() + /** @type {{ js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream }} */ + const {js, dts} = serverLibraryProject.src() .pipe(sourcemaps.init()) - .pipe(newer({ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] })) + .pipe(newer(/** @type {*} */({ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] }))) .pipe(serverLibraryProject()); return merge2([ @@ -555,7 +574,8 @@ const specWord = path.join(docDirectory, "TypeScript Language Specification.docx const specMd = path.join(docDirectory, "spec.md"); gulp.task(word2mdJs, /*help*/ false, [], () => { - const settings: tsc.Settings = getCompilerSettings({ + /** @type {tsc.Settings} */ + const settings = getCompilerSettings({ outFile: word2mdJs }, /*useBuiltCompiler*/ false); return gulp.src(word2mdTs) @@ -634,7 +654,8 @@ function deleteTemporaryProjectOutput() { return del(path.join(localBaseline, "projectOutput/")); } -let savedNodeEnv: string; +/** @type {string} */ +let savedNodeEnv; function setNodeEnvToDevelopment() { savedNodeEnv = process.env.NODE_ENV; process.env.NODE_ENV = "development"; @@ -644,7 +665,12 @@ function restoreSavedNodeEnv() { process.env.NODE_ENV = savedNodeEnv; } -function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) { +/** + * @param {string} defaultReporter + * @param {boolean} runInParallel + * @param {(e?: any) => void} done + */ +function runConsoleTests(defaultReporter, runInParallel, done) { const lintFlag = cmdLineOptions.lint; cleanTestDirs((err) => { if (err) { console.error(err); failWithStatus(err, 1); } @@ -719,7 +745,11 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: } }); - function failWithStatus(err?: any, status?: number) { + /** + * @param {any=} err + * @param {number=} status + */ + function failWithStatus(err, status) { if (err || status) { process.exit(typeof status === "number" ? status : 2); } @@ -735,7 +765,11 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: } } - function finish(error?: any, errorStatus?: number) { + /** + * @param {any=} error + * @param {number=} errorStatus + */ + function finish(error, errorStatus) { restoreSavedNodeEnv(); deleteTestConfig().then(deleteTemporaryProjectOutput).then(() => { if (error !== undefined || errorStatus !== undefined) { @@ -765,7 +799,8 @@ gulp.task("runtests", const nodeServerOutFile = "tests/webTestServer.js"; const nodeServerInFile = "tests/webTestServer.ts"; gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => { - const settings: tsc.Settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ true); + /** @type {tsc.Settings} */ + const settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ true); return gulp.src(nodeServerInFile) .pipe(newer(nodeServerOutFile)) .pipe(sourcemaps.init()) @@ -774,16 +809,18 @@ gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => { .pipe(gulp.dest(path.dirname(nodeServerOutFile))); }); -import convertMap = require("convert-source-map"); -import sorcery = require("sorcery"); -import Vinyl = require("vinyl"); +const convertMap = require("convert-source-map"); +const sorcery = require("sorcery"); +const Vinyl = require("vinyl"); const bundlePath = path.resolve("built/local/bundle.js"); gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => { const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: bundlePath, inlineSourceMap: true }, /*useBuiltCompiler*/ true)); - let originalMap: any; - let prebundledContent: string; + /** @type {*} */ + let originalMap; + /** @type {string} */ + let prebundledContent; browserify(testProject.src() .pipe(newer(bundlePath)) .pipe(sourcemaps.init()) @@ -847,8 +884,10 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo }); }); - -function cleanTestDirs(done: (e?: any) => void) { +/** + * @param {(e?: any) => void} done + */ +function cleanTestDirs(done) { // Clean the local baselines & Rwc baselines directories del([ localBaseline, @@ -864,8 +903,17 @@ function cleanTestDirs(done: (e?: any) => void) { }); } -// used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests: string, runners: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string, timeout?: number) { +/** + * used to pass data from jake command line directly to run.js + * @param {string} tests + * @param {string} runners + * @param {boolean} light + * @param {string=} taskConfigsFolder + * @param {number=} workerCount + * @param {string=} stackTraceLimit + * @param {number=} timeout + */ +function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, timeout) { const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, runner: runners ? runners.split(",") : undefined, @@ -966,7 +1014,7 @@ gulp.task("baseline-accept-test262", "Makes the most recent test262 test results const webhostPath = "tests/webhost/webtsc.ts"; const webhostJsPath = "tests/webhost/webtsc.js"; gulp.task(webhostJsPath, /*help*/ false, [servicesFile], () => { - const settings: tsc.Settings = getCompilerSettings({ + const settings = getCompilerSettings({ outFile: webhostJsPath }, /*useBuiltCompiler*/ true); return gulp.src(webhostPath) @@ -986,7 +1034,7 @@ gulp.task("webhost", "Builds the tsc web host", [webhostJsPath], () => { const perftscPath = "tests/perftsc.ts"; const perftscJsPath = "built/local/perftsc.js"; gulp.task(perftscJsPath, /*help*/ false, [servicesFile], () => { - const settings: tsc.Settings = getCompilerSettings({ + const settings = getCompilerSettings({ outFile: perftscJsPath }, /*useBuiltCompiler*/ true); return gulp.src(perftscPath) @@ -1017,7 +1065,7 @@ gulp.task(loggedIOJsPath, /*help*/ false, [], (done) => { const instrumenterPath = path.join(harnessDirectory, "instrumenter.ts"); const instrumenterJsPath = path.join(builtLocalDirectory, "instrumenter.js"); gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => { - const settings: tsc.Settings = getCompilerSettings({ + const settings = getCompilerSettings({ module: "commonjs", target: "es5", lib: [ @@ -1044,7 +1092,7 @@ gulp.task("update-sublime", "Updates the sublime plugin's tsserver", ["local", s }); gulp.task("build-rules", "Compiles tslint rules to js", () => { - const settings: tsc.Settings = getCompilerSettings({ module: "commonjs", lib: ["es6"] }, /*useBuiltCompiler*/ false); + const settings = getCompilerSettings({ module: "commonjs", lib: ["es6"] }, /*useBuiltCompiler*/ false); const dest = path.join(builtLocalDirectory, "tslint"); return gulp.src("scripts/tslint/**/*.ts") .pipe(newer({ @@ -1057,51 +1105,6 @@ gulp.task("build-rules", "Compiles tslint rules to js", () => { .pipe(gulp.dest(dest)); }); -const lintTargets = [ - "Gulpfile.ts", - "src/compiler/**/*.ts", - "src/harness/**/*.ts", - "!src/harness/unittests/services/formatting/**/*.ts", - "src/server/**/*.ts", - "scripts/tslint/**/*.ts", - "src/services/**/*.ts", - "tests/*.ts", "tests/webhost/*.ts" // Note: does *not* descend recursively -]; - -function sendNextFile(files: {path: string}[], child: cp.ChildProcess, callback: (failures: number) => void, failures: number) { - const file = files.pop(); - if (file) { - console.log(`Linting '${file.path}'.`); - child.send({ kind: "file", name: file.path }); - } - else { - child.send({ kind: "close" }); - callback(failures); - } -} - -function spawnLintWorker(files: {path: string}[], callback: (failures: number) => void) { - const child = cp.fork("./scripts/parallel-lint"); - let failures = 0; - child.on("message", data => { - switch (data.kind) { - case "result": - if (data.failures > 0) { - failures += data.failures; - console.log(data.output); - } - sendNextFile(files, child, callback, failures); - break; - case "error": - console.error(data.error); - failures++; - sendNextFile(files, child, callback, failures); - break; - } - }); - sendNextFile(files, child, callback, failures); -} - gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => { if (fold.isTravis()) console.log(fold.start("lint")); for (const project of ["scripts/tslint/tsconfig.json", "src/tsconfig-base.json"]) { diff --git a/package.json b/package.json index 5837f72317f..71b5ed71029 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,6 @@ "source-map-support": "latest", "through2": "latest", "travis-fold": "latest", - "ts-node": "latest", "tslint": "latest", "vinyl": "latest", "chalk": "latest", From db9620d8f01f1047fe93102bf37527ff30b43c83 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 17 Apr 2018 12:18:49 -0700 Subject: [PATCH 095/229] Use watch recursive directories instead of watchFile for node_modules and bower components --- .../unittests/tsserverProjectSystem.ts | 8 +- src/harness/unittests/typingsInstaller.ts | 30 +++- src/harness/virtualFileSystemWithWatch.ts | 10 +- src/server/types.ts | 2 + .../typingsInstaller/typingsInstaller.ts | 139 ++++++++++++++---- 5 files changed, 151 insertions(+), 38 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 10912b4fb87..a35f797eaa1 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -13,7 +13,9 @@ namespace ts.projectSystem { export import checkArray = TestFSWithWatch.checkArray; export import libFile = TestFSWithWatch.libFile; export import checkWatchedFiles = TestFSWithWatch.checkWatchedFiles; - import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories; + export import checkWatchedFilesDetailed = TestFSWithWatch.checkWatchedFilesDetailed; + export import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories; + export import checkWatchedDirectoriesDetailed = TestFSWithWatch.checkWatchedDirectoriesDetailed; import safeList = TestFSWithWatch.safeList; export const customTypesMap = { @@ -7821,8 +7823,8 @@ namespace ts.projectSystem { checkWatchedDirectories(host, emptyArray, /*recursive*/ true); - TestFSWithWatch.checkMultiMapKeyCount("watchedFiles", host.watchedFiles, expectedWatchedFiles); - TestFSWithWatch.checkMultiMapKeyCount("watchedDirectories", host.watchedDirectories, expectedWatchedDirectories); + checkWatchedFilesDetailed(host, expectedWatchedFiles); + checkWatchedDirectoriesDetailed(host, expectedWatchedDirectories, /*recursive*/ false); checkProjectActualFiles(project, fileNames); } } diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index b6d5a20ef9a..a8c7d4895d1 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -141,7 +141,19 @@ namespace ts.projectSystem { checkNumberOfProjects(projectService, { configuredProjects: 1 }); const p = configuredProjectAt(projectService, 0); checkProjectActualFiles(p, [file1.path, tsconfig.path]); - checkWatchedFiles(host, [tsconfig.path, libFile.path, packageJson.path, "/a/b/bower_components", "/a/b/node_modules"]); + + const expectedWatchedFiles = createMap(); + expectedWatchedFiles.set(tsconfig.path, 1); // tsserver + expectedWatchedFiles.set(libFile.path, 1); // tsserver + expectedWatchedFiles.set(packageJson.path, 1); // typing installer + checkWatchedFilesDetailed(host, expectedWatchedFiles); + + checkWatchedDirectories(host, emptyArray, /*recursive*/ false); + + const expectedWatchedDirectoriesRecursive = createMap(); + expectedWatchedDirectoriesRecursive.set("/a/b", 2); // TypingInstaller and wild card + expectedWatchedDirectoriesRecursive.set("/a/b/node_modules/@types", 1); // type root watch + checkWatchedDirectoriesDetailed(host, expectedWatchedDirectoriesRecursive, /*recursive*/ true); installer.installAll(/*expectedCount*/ 1); @@ -149,7 +161,9 @@ namespace ts.projectSystem { host.checkTimeoutQueueLengthAndRun(2); checkProjectActualFiles(p, [file1.path, jquery.path, tsconfig.path]); // should not watch jquery - checkWatchedFiles(host, [tsconfig.path, libFile.path, packageJson.path, "/a/b/bower_components", "/a/b/node_modules"]); + checkWatchedFilesDetailed(host, expectedWatchedFiles); + checkWatchedDirectories(host, emptyArray, /*recursive*/ false); + checkWatchedDirectoriesDetailed(host, expectedWatchedDirectoriesRecursive, /*recursive*/ true); }); it("inferred project (typings installed)", () => { @@ -827,7 +841,17 @@ namespace ts.projectSystem { checkNumberOfProjects(projectService, { configuredProjects: 1 }); const p = configuredProjectAt(projectService, 0); checkProjectActualFiles(p, [app.path, jsconfig.path]); - checkWatchedFiles(host, [jsconfig.path, "/bower_components", "/node_modules", libFile.path]); + + const watchedFilesExpected = createMap(); + watchedFilesExpected.set(jsconfig.path, 1); // project files + watchedFilesExpected.set(libFile.path, 1); // project files + checkWatchedFilesDetailed(host, watchedFilesExpected); + + checkWatchedDirectories(host, emptyArray, /*recursive*/ false); + + const watchedRecursiveDirectoriesExpected = createMap(); + watchedRecursiveDirectoriesExpected.set("/", 2); // wild card + type installer + checkWatchedDirectoriesDetailed(host, watchedRecursiveDirectoriesExpected, /*recursive*/ true); installer.installAll(/*expectedCount*/ 1); diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 71b7da2ed14..3756f435d43 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -179,10 +179,18 @@ interface Array {}` checkMapKeys("watchedFiles", host.watchedFiles, expectedFiles); } - export function checkWatchedDirectories(host: TestServerHost, expectedDirectories: string[], recursive = false) { + export function checkWatchedFilesDetailed(host: TestServerHost, expectedFiles: Map) { + checkMultiMapKeyCount("watchedFiles", host.watchedFiles, expectedFiles); + } + + export function checkWatchedDirectories(host: TestServerHost, expectedDirectories: string[], recursive: boolean) { checkMapKeys(`watchedDirectories${recursive ? " recursive" : ""}`, recursive ? host.watchedDirectoriesRecursive : host.watchedDirectories, expectedDirectories); } + export function checkWatchedDirectoriesDetailed(host: TestServerHost, expectedDirectories: Map, recursive: boolean) { + checkMultiMapKeyCount(`watchedDirectories${recursive ? " recursive" : ""}`, recursive ? host.watchedDirectoriesRecursive : host.watchedDirectories, expectedDirectories); + } + export function checkOutputContains(host: TestServerHost, expected: ReadonlyArray) { const mapExpected = arrayToSet(expected); const mapSeen = createMap(); diff --git a/src/server/types.ts b/src/server/types.ts index d4ddd81c53e..184a121522e 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -119,8 +119,10 @@ declare namespace ts.server { /* @internal */ export interface InstallTypingHost extends JsTyping.TypingResolutionHost { + useCaseSensitiveFileNames: boolean; writeFile(path: string, content: string): void; createDirectory(path: string): void; watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher; + watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher; } } diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index f79564f6f98..0bff32958be 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -64,6 +64,15 @@ namespace ts.server.typingsInstaller { onRequestCompleted: RequestCompletedAction; } + function isPackageOrBowerJson(fileName: string) { + const base = getBaseFileName(fileName); + return base === "package.json" || base === "bower.json"; + } + + function isInNodeModulesOrBowerComponents(f: string) { + return stringContains(f, "/node_modules/") || stringContains(f, "/bower_components/"); + } + type ProjectWatchers = Map & { isInvoked?: boolean; }; export abstract class TypingsInstaller { @@ -73,6 +82,7 @@ namespace ts.server.typingsInstaller { private readonly projectWatchers = createMap(); private safeList: JsTyping.SafeList | undefined; readonly pendingRunRequests: PendingRequest[] = []; + private readonly toCanonicalFileName: GetCanonicalFileName; private installRunCount = 1; private inFlightRequestCount = 0; @@ -86,6 +96,7 @@ namespace ts.server.typingsInstaller { private readonly typesMapLocation: Path, private readonly throttleLimit: number, protected readonly log = nullLog) { + this.toCanonicalFileName = createGetCanonicalFileName(installTypingHost.useCaseSensitiveFileNames); if (this.log.isEnabled()) { this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}', types map path ${typesMapLocation}`); } @@ -147,7 +158,7 @@ namespace ts.server.typingsInstaller { } // start watching files - this.watchFiles(req.projectName, discoverTypingsResult.filesToWatch); + this.watchFiles(req.projectName, discoverTypingsResult.filesToWatch, req.projectRootPath); // install typings if (discoverTypingsResult.newTypingNames.length) { @@ -367,7 +378,7 @@ namespace ts.server.typingsInstaller { } } - private watchFiles(projectName: string, files: string[]) { + private watchFiles(projectName: string, files: string[], projectRootPath: Path) { if (!files.length) { // shut down existing watchers this.closeWatchers(projectName); @@ -375,43 +386,109 @@ namespace ts.server.typingsInstaller { } let watchers = this.projectWatchers.get(projectName); + const toRemove = createMap(); if (!watchers) { watchers = createMap(); this.projectWatchers.set(projectName, watchers); } + else { + copyEntries(watchers, toRemove); + } - watchers.isInvoked = false; // handler should be invoked once for the entire set of files since it will trigger full rediscovery of typings + watchers.isInvoked = false; + const isLoggingEnabled = this.log.isEnabled(); - mutateMap( - watchers, - arrayToSet(files), - { - // Watch the missing files - createNewValue: file => { - if (isLoggingEnabled) { - this.log.writeLine(`FileWatcher:: Added:: WatchInfo: ${file}`); - } - const watcher = this.installTypingHost.watchFile(file, (f, eventKind) => { - if (isLoggingEnabled) { - this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${watchers.isInvoked}'`); - } - if (!watchers.isInvoked) { - watchers.isInvoked = true; - this.sendResponse({ projectName, kind: ActionInvalidate }); - } - }, /*pollingInterval*/ 2000); - return isLoggingEnabled ? { - close: () => { - this.log.writeLine(`FileWatcher:: Closed:: WatchInfo: ${file}`); - } - } : watcher; - }, - // Files that are no longer missing (e.g. because they are no longer required) - // should no longer be watched. - onDeleteValue: closeFileWatcher + const createProjectWatcher = (path: string, createWatch: (path: string) => FileWatcher) => { + toRemove.delete(path); + if (watchers.has(path)) { + return; } - ); + + watchers.set(path, createWatch(path)); + }; + const createProjectFileWatcher = (file: string): FileWatcher => { + if (isLoggingEnabled) { + this.log.writeLine(`FileWatcher:: Added:: WatchInfo: ${file}`); + } + const watcher = this.installTypingHost.watchFile(file, (f, eventKind) => { + if (isLoggingEnabled) { + this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${watchers.isInvoked}'`); + } + if (!watchers.isInvoked) { + watchers.isInvoked = true; + this.sendResponse({ projectName, kind: ActionInvalidate }); + } + }, /*pollingInterval*/ 2000); + + return isLoggingEnabled ? { + close: () => { + this.log.writeLine(`FileWatcher:: Closed:: WatchInfo: ${file}`); + watcher.close(); + } + } : watcher; + }; + const createProjectDirectoryWatcher = (dir: string): FileWatcher => { + if (isLoggingEnabled) { + this.log.writeLine(`DirectoryWatcher:: Added:: WatchInfo: ${dir} recursive`); + } + const watcher = this.installTypingHost.watchDirectory(dir, f => { + if (isLoggingEnabled) { + this.log.writeLine(`DirectoryWatcher:: Triggered with ${f} :: WatchInfo: ${dir} recursive :: handler is already invoked '${watchers.isInvoked}'`); + } + if (watchers.isInvoked) { + return; + } + f = this.toCanonicalFileName(f); + if (isPackageOrBowerJson(f) && f !== this.toCanonicalFileName(combinePaths(this.globalCachePath, "package.json"))) { + watchers.isInvoked = true; + this.sendResponse({ projectName, kind: ActionInvalidate }); + } + }, /*recursive*/ true); + + return isLoggingEnabled ? { + close: () => { + this.log.writeLine(`DirectoryWatcher:: Closed:: WatchInfo: ${dir} recursive`); + watcher.close(); + } + } : watcher; + }; + + // Create watches from list of files + for (const file of files) { + const filePath = this.toCanonicalFileName(file); + if (isPackageOrBowerJson(filePath)) { + // package.json or bower.json exists, watch the file to detect changes and update typings + createProjectWatcher(filePath, createProjectFileWatcher); + continue; + } + + // path in projectRoot, watch project root + if (containsPath(projectRootPath, filePath, projectRootPath, !this.installTypingHost.useCaseSensitiveFileNames)) { + createProjectWatcher(projectRootPath, createProjectDirectoryWatcher); + continue; + } + + // path in global cache, watch global cache + if (containsPath(this.globalCachePath, filePath, projectRootPath, !this.installTypingHost.useCaseSensitiveFileNames)) { + createProjectWatcher(this.globalCachePath, createProjectDirectoryWatcher); + continue; + } + + // Get path without node_modules and bower_components + let pathToWatch = getDirectoryPath(filePath); + while (isInNodeModulesOrBowerComponents(pathToWatch)) { + pathToWatch = getDirectoryPath(pathToWatch); + } + + createProjectWatcher(pathToWatch, createProjectDirectoryWatcher); + } + + // Remove unused watches + toRemove.forEach((watch, path) => { + watch.close(); + watchers.delete(path); + }); } private createSetTypings(request: DiscoverTypings, typings: string[]): SetTypings { From f5101e21c36f19cbd30ae32b6945618a3e9dc98d Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 17 Apr 2018 15:01:36 -0700 Subject: [PATCH 096/229] Find-all-references: Don't crash on 'typeof import' (#23448) * Find-all-references: Don't crash on 'typeof import' * Move `| ImportTypeNode` out of `AnyImportOrReExport` --- src/compiler/types.ts | 3 ++- src/compiler/utilities.ts | 8 +++++++- src/services/importTracker.ts | 6 +++++- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + tests/cases/fourslash/findAllRefsTypeofImport.ts | 8 ++++++++ 6 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/findAllRefsTypeofImport.ts diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 63720d55900..d038d4281b0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3193,7 +3193,8 @@ namespace ts { export type AnyValidImportOrReExport = | (ImportDeclaration | ExportDeclaration) & { moduleSpecifier: StringLiteral } | ImportEqualsDeclaration & { moduleReference: ExternalModuleReference & { expression: StringLiteral } } - | RequireOrImportCall; + | RequireOrImportCall + | ImportTypeNode & { argument: LiteralType }; /* @internal */ export type RequireOrImportCall = CallExpression & { arguments: [StringLiteralLike] }; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f975e27dca3..e9d6f026b4e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1710,8 +1710,10 @@ namespace ts { return (node.parent as ExternalModuleReference).parent as AnyValidImportOrReExport; case SyntaxKind.CallExpression: return node.parent as AnyValidImportOrReExport; + case SyntaxKind.LiteralType: + return cast(node.parent.parent, isImportTypeNode) as ImportTypeNode & { argument: LiteralType }; default: - return Debug.fail(Debug.showSyntaxKind(node)); + return Debug.fail(Debug.showSyntaxKind(node.parent)); } } @@ -4926,6 +4928,10 @@ namespace ts { return node.kind === SyntaxKind.LiteralType; } + export function isImportTypeNode(node: Node): node is ImportTypeNode { + return node.kind === SyntaxKind.ImportType; + } + // Binding patterns export function isObjectBindingPattern(node: Node): node is ObjectBindingPattern { diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 82f9fc00af6..80f0721e642 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -33,7 +33,7 @@ namespace ts.FindAllReferences { interface AmbientModuleDeclaration extends ModuleDeclaration { body?: ModuleBlock; } type SourceFileLike = SourceFile | AmbientModuleDeclaration; // Identifier for the case of `const x = require("y")`. - type Importer = AnyImportOrReExport | Identifier; + type Importer = AnyImportOrReExport | ImportTypeNode | Identifier; type ImporterOrCallExpression = Importer | CallExpression; /** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */ @@ -215,6 +215,10 @@ namespace ts.FindAllReferences { return; } + if (decl.kind === SyntaxKind.ImportType) { + return; + } + // Ignore if there's a grammar error if (decl.moduleSpecifier.kind !== SyntaxKind.StringLiteral) { return; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 04fabe6ff09..f5f60338aa9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3169,6 +3169,7 @@ declare namespace ts { function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode; function isMappedTypeNode(node: Node): node is MappedTypeNode; function isLiteralTypeNode(node: Node): node is LiteralTypeNode; + function isImportTypeNode(node: Node): node is ImportTypeNode; function isObjectBindingPattern(node: Node): node is ObjectBindingPattern; function isArrayBindingPattern(node: Node): node is ArrayBindingPattern; function isBindingElement(node: Node): node is BindingElement; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 506aa6b15c6..b64ef40646c 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3169,6 +3169,7 @@ declare namespace ts { function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode; function isMappedTypeNode(node: Node): node is MappedTypeNode; function isLiteralTypeNode(node: Node): node is LiteralTypeNode; + function isImportTypeNode(node: Node): node is ImportTypeNode; function isObjectBindingPattern(node: Node): node is ObjectBindingPattern; function isArrayBindingPattern(node: Node): node is ArrayBindingPattern; function isBindingElement(node: Node): node is BindingElement; diff --git a/tests/cases/fourslash/findAllRefsTypeofImport.ts b/tests/cases/fourslash/findAllRefsTypeofImport.ts new file mode 100644 index 00000000000..77bd2d51a8c --- /dev/null +++ b/tests/cases/fourslash/findAllRefsTypeofImport.ts @@ -0,0 +1,8 @@ +/// + +// @Filename: /a.ts +////export const [|{| "isWriteAccess": true, "isDefinition": true |}x|] = 0; +////declare const a: typeof import("./a"); +////a.[|x|]; + +verify.singleReferenceGroup("const x: 0"); From e26745f129404109948f91d6803e92f5f14c24b6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 17 Apr 2018 15:20:48 -0700 Subject: [PATCH 097/229] Add axios' source to user tests (#23490) * Add axios' source to user tests We already have the npm-installed version in order to test their d.ts so that we don't break their users. * Just compile lib, plus fix some config lint --- .gitmodules | 5 +++ tests/baselines/reference/user/axios-src.log | 44 ++++++++++++++++++++ tests/cases/user/axios-src/axios-src | 1 + tests/cases/user/axios-src/test.json | 3 ++ tests/cases/user/axios-src/tsconfig.json | 14 +++++++ 5 files changed, 67 insertions(+) create mode 100644 tests/baselines/reference/user/axios-src.log create mode 160000 tests/cases/user/axios-src/axios-src create mode 100644 tests/cases/user/axios-src/test.json create mode 100644 tests/cases/user/axios-src/tsconfig.json diff --git a/.gitmodules b/.gitmodules index ccb2be81520..fdf474a693d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -29,3 +29,8 @@ [submodule "tests/cases/user/puppeteer/puppeteer"] path = tests/cases/user/puppeteer/puppeteer url = https://github.com/GoogleChrome/puppeteer.git + ignore = all +[submodule "tests/cases/user/axios-src/axios-src"] + path = tests/cases/user/axios-src/axios-src + url = https://github.com/axios/axios.git + ignore = all diff --git a/tests/baselines/reference/user/axios-src.log b/tests/baselines/reference/user/axios-src.log new file mode 100644 index 00000000000..ad8bc285bbb --- /dev/null +++ b/tests/baselines/reference/user/axios-src.log @@ -0,0 +1,44 @@ +Exit Code: 1 +Standard output: +lib/adapters/http.js(12,19): error TS2307: Cannot find module './../../package.json'. +lib/adapters/http.js(83,22): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'. + Type 'undefined' is not assignable to type 'string'. +lib/adapters/http.js(189,23): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(195,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(201,13): error TS2322: Type 'string' is not assignable to type 'Buffer'. +lib/adapters/http.js(213,40): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/http.js(237,42): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/xhr.js(29,16): error TS2339: Property 'XDomainRequest' does not exist on type 'Window'. +lib/adapters/xhr.js(31,28): error TS2339: Property 'XDomainRequest' does not exist on type 'Window'. +lib/adapters/xhr.js(80,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. +lib/adapters/xhr.js(92,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. +lib/adapters/xhr.js(99,51): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/adapters/xhr.js(102,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. +lib/adapters/xhr.js(111,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. +lib/adapters/xhr.js(181,9): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'. +lib/axios.js(23,3): error TS2554: Expected 3 arguments, but got 2. +lib/axios.js(25,3): error TS2322: Type '(...args: any[]) => any' is not assignable to type 'Axios'. + Property 'defaults' is missing in type '(...args: any[]) => any'. +lib/axios.js(32,7): error TS2339: Property 'Axios' does not exist on type 'Axios'. +lib/axios.js(35,7): error TS2339: Property 'create' does not exist on type 'Axios'. +lib/axios.js(40,7): error TS2339: Property 'Cancel' does not exist on type 'Axios'. +lib/axios.js(41,7): error TS2339: Property 'CancelToken' does not exist on type 'Axios'. +lib/axios.js(42,7): error TS2339: Property 'isCancel' does not exist on type 'Axios'. +lib/axios.js(45,7): error TS2339: Property 'all' does not exist on type 'Axios'. +lib/axios.js(48,7): error TS2339: Property 'spread' does not exist on type 'Axios'. +lib/cancel/CancelToken.js(37,12): error TS2339: Property 'reason' does not exist on type 'CancelToken'. +lib/cancel/CancelToken.js(38,16): error TS2339: Property 'reason' does not exist on type 'CancelToken'. +lib/core/enhanceError.js(14,9): error TS2339: Property 'config' does not exist on type 'Error'. +lib/core/enhanceError.js(16,11): error TS2339: Property 'code' does not exist on type 'Error'. +lib/core/enhanceError.js(18,9): error TS2339: Property 'request' does not exist on type 'Error'. +lib/core/enhanceError.js(19,9): error TS2339: Property 'response' does not exist on type 'Error'. +lib/core/settle.js(21,7): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'. +lib/helpers/btoa.js(11,13): error TS2339: Property 'code' does not exist on type 'Error'. +lib/helpers/btoa.js(31,13): error TS2532: Object is possibly 'undefined'. +lib/helpers/cookies.js(16,56): error TS2551: Property 'toGMTString' does not exist on type 'Date'. Did you mean 'toUTCString'? +lib/utils.js(244,20): error TS8029: JSDoc '@param' tag has name 'obj1', but there is no parameter with that name. It would match 'arguments' if it had an array type. +lib/utils.js(268,20): error TS8029: JSDoc '@param' tag has name 'obj1', but there is no parameter with that name. It would match 'arguments' if it had an array type. + + + +Standard error: diff --git a/tests/cases/user/axios-src/axios-src b/tests/cases/user/axios-src/axios-src new file mode 160000 index 00000000000..0b3db5d87a6 --- /dev/null +++ b/tests/cases/user/axios-src/axios-src @@ -0,0 +1 @@ +Subproject commit 0b3db5d87a60a1ad8b0dce9669dbc10483ec33da diff --git a/tests/cases/user/axios-src/test.json b/tests/cases/user/axios-src/test.json new file mode 100644 index 00000000000..b6495a1b80b --- /dev/null +++ b/tests/cases/user/axios-src/test.json @@ -0,0 +1,3 @@ +{ + "types": ["node"] +} diff --git a/tests/cases/user/axios-src/tsconfig.json b/tests/cases/user/axios-src/tsconfig.json new file mode 100644 index 00000000000..ef3f63dc126 --- /dev/null +++ b/tests/cases/user/axios-src/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "noImplicitAny": false, + "noImplicitThis": false, + "maxNodeModuleJsDepth": 0, + "strict": true, + "noEmit": true, + "allowJs": true, + "checkJs": true, + "types": ["node"], + "lib": ["esnext", "dom"], + }, + "include": ["axios-src/lib"] +} From b11be803490d5a94c81adfe6fc3b5e20608ac581 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 17 Apr 2018 16:29:42 -0700 Subject: [PATCH 098/229] Don't widen unique symbol types during type inference --- src/compiler/checker.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7ffe7126388..507d9129334 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12372,14 +12372,13 @@ namespace ts { inferredType = getTypeFromInference(inference); } - inferredType = getWidenedUniqueESSymbolType(inferredType); inference.inferredType = inferredType; const constraint = getConstraintOfTypeParameter(inference.typeParameter); if (constraint) { const instantiatedConstraint = instantiateType(constraint, context); if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { - inference.inferredType = inferredType = getWidenedUniqueESSymbolType(instantiatedConstraint); + inference.inferredType = inferredType = instantiatedConstraint; } } } From 02534cca315abb9f99e35a88aa45fd0f6005daf5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 17 Apr 2018 16:29:49 -0700 Subject: [PATCH 099/229] Accept new baselines --- tests/baselines/reference/uniqueSymbols.types | 10 +++++----- tests/baselines/reference/uniqueSymbolsDeclarations.js | 2 +- .../reference/uniqueSymbolsDeclarations.types | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/baselines/reference/uniqueSymbols.types b/tests/baselines/reference/uniqueSymbols.types index 621d3df4236..55ce8d9c87e 100644 --- a/tests/baselines/reference/uniqueSymbols.types +++ b/tests/baselines/reference/uniqueSymbols.types @@ -402,8 +402,8 @@ const constInitToLReadonlyNestedTypeWithIndexedAccess: L["nested"]["readonlyNest // type argument inference const promiseForConstCall = Promise.resolve(constCall); ->promiseForConstCall : Promise ->Promise.resolve(constCall) : Promise +>promiseForConstCall : Promise +>Promise.resolve(constCall) : Promise >Promise.resolve : { (value: T | PromiseLike): Promise; (): Promise; } >Promise : PromiseConstructor >resolve : { (value: T | PromiseLike): Promise; (): Promise; } @@ -454,19 +454,19 @@ declare function g(x: typeof N.s): void; // argument inference f(s); ->f(s) : symbol +>f(s) : unique symbol >f : (x: T) => T >s : unique symbol f(N.s); ->f(N.s) : symbol +>f(N.s) : unique symbol >f : (x: T) => T >N.s : unique symbol >N : typeof N >s : unique symbol f(N["s"]); ->f(N["s"]) : symbol +>f(N["s"]) : unique symbol >f : (x: T) => T >N["s"] : unique symbol >N : typeof N diff --git a/tests/baselines/reference/uniqueSymbolsDeclarations.js b/tests/baselines/reference/uniqueSymbolsDeclarations.js index 6b52b210977..728c507c747 100644 --- a/tests/baselines/reference/uniqueSymbolsDeclarations.js +++ b/tests/baselines/reference/uniqueSymbolsDeclarations.js @@ -482,7 +482,7 @@ declare const constInitToLReadonlyTypeWithTypeQuery: typeof l.readonlyType; declare const constInitToLReadonlyNestedTypeWithTypeQuery: typeof l.nested.readonlyNestedType; declare const constInitToLReadonlyTypeWithIndexedAccess: L["readonlyType"]; declare const constInitToLReadonlyNestedTypeWithIndexedAccess: L["nested"]["readonlyNestedType"]; -declare const promiseForConstCall: Promise; +declare const promiseForConstCall: Promise; declare const arrayOfConstCall: symbol[]; declare const s: unique symbol; declare namespace N { diff --git a/tests/baselines/reference/uniqueSymbolsDeclarations.types b/tests/baselines/reference/uniqueSymbolsDeclarations.types index a841354269f..6bfee5a0403 100644 --- a/tests/baselines/reference/uniqueSymbolsDeclarations.types +++ b/tests/baselines/reference/uniqueSymbolsDeclarations.types @@ -402,8 +402,8 @@ const constInitToLReadonlyNestedTypeWithIndexedAccess: L["nested"]["readonlyNest // type argument inference const promiseForConstCall = Promise.resolve(constCall); ->promiseForConstCall : Promise ->Promise.resolve(constCall) : Promise +>promiseForConstCall : Promise +>Promise.resolve(constCall) : Promise >Promise.resolve : { (value: T | PromiseLike): Promise; (): Promise; } >Promise : PromiseConstructor >resolve : { (value: T | PromiseLike): Promise; (): Promise; } @@ -454,19 +454,19 @@ declare function g(x: typeof N.s): void; // argument inference f(s); ->f(s) : symbol +>f(s) : unique symbol >f : (x: T) => T >s : unique symbol f(N.s); ->f(N.s) : symbol +>f(N.s) : unique symbol >f : (x: T) => T >N.s : unique symbol >N : typeof N >s : unique symbol f(N["s"]); ->f(N["s"]) : symbol +>f(N["s"]) : unique symbol >f : (x: T) => T >N["s"] : unique symbol >N : typeof N From 6953fa17328809c0b4db08e9a91adb2196957496 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 17 Apr 2018 17:06:50 -0700 Subject: [PATCH 100/229] flags--; --- src/compiler/commandLineParser.ts | 8 -------- src/compiler/tsc.ts | 4 ++-- src/compiler/types.ts | 8 -------- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 2de922b4159..470bd111492 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -56,14 +56,6 @@ namespace ts { category: Diagnostics.Command_line_Options, description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, - { - name: "diagnosticStyle", - type: createMapFromTemplate({ - auto: DiagnosticStyle.Auto, - pretty: DiagnosticStyle.Pretty, - simple: DiagnosticStyle.Simple, - }), - }, { name: "preserveWatchOutput", type: "boolean", diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 56c3c323f30..b2bffd83ca7 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -25,10 +25,10 @@ namespace ts { } function shouldBePretty(options: CompilerOptions) { - if ((typeof options.pretty === "undefined" && typeof options.diagnosticStyle === "undefined") || options.diagnosticStyle === DiagnosticStyle.Auto) { + if ((typeof options.pretty === "undefined")) { return !!sys.writeOutputIsTty && sys.writeOutputIsTty(); } - return options.diagnosticStyle === DiagnosticStyle.Pretty || options.pretty; + return options.pretty; } function padLeft(s: string, length: number) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 802c175b573..8962a7d0280 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4194,7 +4194,6 @@ namespace ts { /* @internal */ preserveWatchOutput?: boolean; project?: string; /* @internal */ pretty?: boolean; - /* @internal */ diagnosticStyle?: DiagnosticStyle; reactNamespace?: string; jsxFactory?: string; removeComments?: boolean; @@ -4292,13 +4291,6 @@ namespace ts { JSX, } - /* @internal */ - export const enum DiagnosticStyle { - Auto, - Pretty, - Simple, - } - /** Either a parsed command line or a parsed tsconfig.json */ export interface ParsedCommandLine { options: CompilerOptions; From 563660a83a35b460156d53e455eaf1c7fab42523 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Wed, 18 Apr 2018 11:22:22 +0900 Subject: [PATCH 101/229] Revert the change of PromiseLikeConstructor --- src/lib/es5.d.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index c213677feac..1f352cd6f39 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1273,9 +1273,7 @@ declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) declare type MethodDecorator = (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor | void; declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void; -interface PromiseConstructorLike { - new (executor: (resolve: [T] extends [void] ? (value?: T | PromiseLike) => void : (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void): PromiseLike; -} +declare type PromiseConstructorLike = new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void) => PromiseLike; interface PromiseLike { /** From 26c836b12a56063ddde7586cdf37127ba174a7f5 Mon Sep 17 00:00:00 2001 From: Andrew Casey Date: Tue, 17 Apr 2018 19:44:52 -0700 Subject: [PATCH 102/229] Propagage reportsUnnecessary in convertToDiagnosticsWithLinePosition --- src/server/session.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/session.ts b/src/server/session.ts index 1076d17e11f..27044ec369d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -634,7 +634,8 @@ namespace ts.server { code: d.code, source: d.source, startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start), - endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length) + endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length), + reportsUnnecessary: d.reportsUnnecessary }); } From 4318f0d9a0bd17cf4a7c502c3fe57c8538efa5c0 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Wed, 18 Apr 2018 11:45:01 +0900 Subject: [PATCH 103/229] Improve PromiseConstructor --- src/lib/es2015.promise.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/es2015.promise.d.ts b/src/lib/es2015.promise.d.ts index af43abe63d6..65986e85baf 100644 --- a/src/lib/es2015.promise.d.ts +++ b/src/lib/es2015.promise.d.ts @@ -10,7 +10,7 @@ interface PromiseConstructor { * a resolve callback used resolve the promise with a value or the result of another promise, * and a reject callback used to reject the promise with a provided reason or error. */ - new (executor: (resolve: [T] extends [void] ? (value?: T | PromiseLike) => void : (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; + new (executor: (resolve: [void] extends [T] ? (value?: T | PromiseLike) => void : (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises From 81b347d61da5ba100bd09fef6d863520e6c48a21 Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 18 Apr 2018 04:10:18 +0000 Subject: [PATCH 104/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 58326d7ccb6..b2ffdf585e0 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -3894,6 +3894,15 @@ + + + + + + + + + @@ -6003,6 +6012,9 @@ + + + From afde2b5bf3d90526493dbb2ef40553be0ca48d17 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 18 Apr 2018 07:55:57 -0700 Subject: [PATCH 105/229] MissingDeclaration is only ever a Statement (#23485) --- src/compiler/types.ts | 2 +- src/compiler/utilities.ts | 9 +++------ tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d038d4281b0..19034c3469e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1892,7 +1892,7 @@ namespace ts { kind: SyntaxKind.DebuggerStatement; } - export interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement { + export interface MissingDeclaration extends DeclarationStatement { kind: SyntaxKind.MissingDeclaration; name?: Identifier; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e9d6f026b4e..3fe255fb612 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5612,8 +5612,7 @@ namespace ts { || kind === SyntaxKind.GetAccessor || kind === SyntaxKind.SetAccessor || kind === SyntaxKind.IndexSignature - || kind === SyntaxKind.SemicolonClassElement - || kind === SyntaxKind.MissingDeclaration; + || kind === SyntaxKind.SemicolonClassElement; } export function isClassLike(node: Node): node is ClassLikeDeclaration { @@ -5644,8 +5643,7 @@ namespace ts { || kind === SyntaxKind.CallSignature || kind === SyntaxKind.PropertySignature || kind === SyntaxKind.MethodSignature - || kind === SyntaxKind.IndexSignature - || kind === SyntaxKind.MissingDeclaration; + || kind === SyntaxKind.IndexSignature; } export function isClassOrTypeElement(node: Node): node is ClassElement | TypeElement { @@ -5659,8 +5657,7 @@ namespace ts { || kind === SyntaxKind.SpreadAssignment || kind === SyntaxKind.MethodDeclaration || kind === SyntaxKind.GetAccessor - || kind === SyntaxKind.SetAccessor - || kind === SyntaxKind.MissingDeclaration; + || kind === SyntaxKind.SetAccessor; } // Type diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index f5f60338aa9..fe1f28e1181 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1160,7 +1160,7 @@ declare namespace ts { interface DebuggerStatement extends Statement { kind: SyntaxKind.DebuggerStatement; } - interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement { + interface MissingDeclaration extends DeclarationStatement { kind: SyntaxKind.MissingDeclaration; name?: Identifier; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b64ef40646c..16edf86582e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1160,7 +1160,7 @@ declare namespace ts { interface DebuggerStatement extends Statement { kind: SyntaxKind.DebuggerStatement; } - interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement { + interface MissingDeclaration extends DeclarationStatement { kind: SyntaxKind.MissingDeclaration; name?: Identifier; } From b14d38908520a15f9dd582f8c7980c6acd7dac62 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 18 Apr 2018 11:01:09 -0700 Subject: [PATCH 106/229] For 'T extends { [x: string]: XXX }' constraint of T[keyof T] is XXX --- src/compiler/checker.ts | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 507d9129334..67867074fdb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8230,8 +8230,9 @@ namespace ts { maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, includeDeclaredTypes) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : - type.flags & TypeFlags.Any || getIndexInfoOfType(type, IndexKind.String) ? keyofConstraintType : - keyofStringsOnly ? getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : + type.flags & TypeFlags.Any ? keyofConstraintType : + keyofStringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : + getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : getLiteralTypeFromPropertyNames(type, TypeFlags.StringOrNumberLiteralOrUnique); } @@ -8303,7 +8304,11 @@ namespace ts { getIndexInfoOfType(objectType, IndexKind.String) || undefined; if (indexInfo) { - if (accessExpression && indexInfo.isReadonly && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) { + if (accessNode && !isTypeAssignableToKind(indexType, TypeFlags.String | TypeFlags.Number)) { + const indexNode = accessNode.kind === SyntaxKind.ElementAccessExpression ? accessNode.argumentExpression : accessNode.indexType; + error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); + } + else if (accessExpression && indexInfo.isReadonly && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) { error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); } return indexInfo.type; @@ -20055,6 +20060,15 @@ namespace ts { return widened; } + function isTypeParameterWithKeyofConstraint(type: Type) { + if (type.flags & TypeFlags.TypeParameter) { + const constraintDeclaration = getConstraintDeclaration(type); + return constraintDeclaration && constraintDeclaration.kind === SyntaxKind.TypeOperator && + (constraintDeclaration).operator === SyntaxKind.KeyOfKeyword; + } + return false; + } + function isLiteralOfContextualType(candidateType: Type, contextualType: Type): boolean { if (contextualType) { if (contextualType.flags & TypeFlags.UnionOrIntersection) { @@ -20066,7 +20080,7 @@ namespace ts { // this a literal context for literals of that primitive type. For example, given a // type parameter 'T extends string', infer string literal types for T. const constraint = getBaseConstraintOfType(contextualType) || emptyObjectType; - return constraint === keyofConstraintType && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol) || + return isTypeParameterWithKeyofConstraint(contextualType) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.UniqueESSymbol) || constraint.flags & TypeFlags.String && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) || constraint.flags & TypeFlags.Number && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) || constraint.flags & TypeFlags.Boolean && maybeTypeOfKind(candidateType, TypeFlags.BooleanLiteral) || From 254782c06fe17356477531806a3219d8fbc9efc1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 18 Apr 2018 11:01:25 -0700 Subject: [PATCH 107/229] Accept new baselines --- tests/baselines/reference/keyofAndIndexedAccess.types | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 7e2d80d6b9c..4e41b58e664 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -92,7 +92,7 @@ type K11 = keyof Shape[]; // "length" | "toString" | ... >Shape : Shape type K12 = keyof Dictionary; // string ->K12 : string | number | symbol +>K12 : string | number >Dictionary : Dictionary >Shape : Shape @@ -136,7 +136,7 @@ type K20 = KeyOf; // "name" | "width" | "height" | "visible" >Shape : Shape type K21 = KeyOf>; // string ->K21 : string | number | symbol +>K21 : string | number >KeyOf : keyof T >Dictionary : Dictionary >Shape : Shape From 7c5f5249ae0a7b5be78d4f3549860e532208073d Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 18 Apr 2018 11:05:56 -0700 Subject: [PATCH 108/229] Renames as per PR feedback --- src/server/project.ts | 12 ++++++------ src/server/scriptInfo.ts | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/server/project.ts b/src/server/project.ts index 653f2943d0a..92645cfca52 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -99,7 +99,7 @@ namespace ts.server { /*@internal*/ lastCachedUnresolvedImportsList: SortedReadonlyArray; /*@internal*/ - private hasMoreOrLessFiles = false; + private hasAddedorRemovedFiles = false; private lastFileExceededProgramSize: string | undefined; @@ -777,8 +777,8 @@ namespace ts.server { } /* @internal */ - setHasMoreOrLessFiles() { - this.hasMoreOrLessFiles = true; + onFileAddedOrRemoved() { + this.hasAddedorRemovedFiles = true; } /** @@ -789,8 +789,8 @@ namespace ts.server { this.resolutionCache.startRecordingFilesWithChangedResolutions(); const hasNewProgram = this.updateGraphWorker(); - const hasMoreOrLessFiles = this.hasMoreOrLessFiles; - this.hasMoreOrLessFiles = false; + const hasAddedorRemovedFiles = this.hasAddedorRemovedFiles; + this.hasAddedorRemovedFiles = false; const changedFiles: ReadonlyArray = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || emptyArray; @@ -820,7 +820,7 @@ namespace ts.server { this.lastCachedUnresolvedImportsList = result ? toDeduplicatedSortedArray(result) : emptyArray; } - this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasMoreOrLessFiles); + this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasAddedorRemovedFiles); } else { this.lastCachedUnresolvedImportsList = undefined; diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index cc4ebd519e5..589975769b1 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -304,7 +304,7 @@ namespace ts.server { const isNew = !this.isAttached(project); if (isNew) { this.containingProjects.push(project); - project.setHasMoreOrLessFiles(); + project.onFileAddedOrRemoved(); if (!project.getCompilerOptions().preserveSymlinks) { this.ensureRealPath(); } @@ -329,23 +329,23 @@ namespace ts.server { return; case 1: if (this.containingProjects[0] === project) { - project.setHasMoreOrLessFiles(); + project.onFileAddedOrRemoved(); this.containingProjects.pop(); } break; case 2: if (this.containingProjects[0] === project) { - project.setHasMoreOrLessFiles(); + project.onFileAddedOrRemoved(); this.containingProjects[0] = this.containingProjects.pop(); } else if (this.containingProjects[1] === project) { - project.setHasMoreOrLessFiles(); + project.onFileAddedOrRemoved(); this.containingProjects.pop(); } break; default: if (unorderedRemoveItem(this.containingProjects, project)) { - project.setHasMoreOrLessFiles(); + project.onFileAddedOrRemoved(); } break; } From 67bb67edf15ace4122253418a339f3c08c68ee3e Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 18 Apr 2018 11:22:02 -0700 Subject: [PATCH 109/229] Cache canonical global cache's package.json path --- src/server/typingsInstaller/typingsInstaller.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 0bff32958be..463851e96f4 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -83,6 +83,7 @@ namespace ts.server.typingsInstaller { private safeList: JsTyping.SafeList | undefined; readonly pendingRunRequests: PendingRequest[] = []; private readonly toCanonicalFileName: GetCanonicalFileName; + private readonly globalCacheCanonicalPackageJsonPath: string; private installRunCount = 1; private inFlightRequestCount = 0; @@ -97,6 +98,7 @@ namespace ts.server.typingsInstaller { private readonly throttleLimit: number, protected readonly log = nullLog) { this.toCanonicalFileName = createGetCanonicalFileName(installTypingHost.useCaseSensitiveFileNames); + this.globalCacheCanonicalPackageJsonPath = combinePaths(this.toCanonicalFileName(globalCachePath), "package.json"); if (this.log.isEnabled()) { this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}', types map path ${typesMapLocation}`); } @@ -440,7 +442,7 @@ namespace ts.server.typingsInstaller { return; } f = this.toCanonicalFileName(f); - if (isPackageOrBowerJson(f) && f !== this.toCanonicalFileName(combinePaths(this.globalCachePath, "package.json"))) { + if (f !== this.globalCacheCanonicalPackageJsonPath && isPackageOrBowerJson(f)) { watchers.isInvoked = true; this.sendResponse({ projectName, kind: ActionInvalidate }); } From 56b618b9fcb92a1363fcf1cced19062bfd0c3129 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 18 Apr 2018 11:44:28 -0700 Subject: [PATCH 110/229] Use indexOf and substr to exclude node_modules and bowerComponents instead of using loop --- src/server/typingsInstaller/typingsInstaller.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 463851e96f4..7d8cf02fab0 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -69,8 +69,13 @@ namespace ts.server.typingsInstaller { return base === "package.json" || base === "bower.json"; } - function isInNodeModulesOrBowerComponents(f: string) { - return stringContains(f, "/node_modules/") || stringContains(f, "/bower_components/"); + function getDirectoryExcludingNodeModulesOrBowerComponents(f: string) { + const indexOfNodeModules = f.indexOf("/node_modules/"); + const indexOfBowerComponents = f.indexOf("/bower_components/"); + const subStrLength = indexOfNodeModules === -1 || indexOfBowerComponents === -1 ? + Math.max(indexOfNodeModules, indexOfBowerComponents) : + Math.min(indexOfNodeModules, indexOfBowerComponents); + return subStrLength === -1 ? f : f.substr(0, subStrLength); } type ProjectWatchers = Map & { isInvoked?: boolean; }; @@ -478,12 +483,7 @@ namespace ts.server.typingsInstaller { } // Get path without node_modules and bower_components - let pathToWatch = getDirectoryPath(filePath); - while (isInNodeModulesOrBowerComponents(pathToWatch)) { - pathToWatch = getDirectoryPath(pathToWatch); - } - - createProjectWatcher(pathToWatch, createProjectDirectoryWatcher); + createProjectWatcher(getDirectoryExcludingNodeModulesOrBowerComponents(getDirectoryPath(filePath)), createProjectDirectoryWatcher); } // Remove unused watches From 320cb40f123d1fa1eb91cd55d9555f8c4e9d81d3 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 18 Apr 2018 10:56:14 -0700 Subject: [PATCH 111/229] Address CR feedback. --- src/compiler/sys.ts | 4 ++-- src/compiler/tsc.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 2a4616732dd..be95e06eb46 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -428,7 +428,7 @@ namespace ts { newLine: string; useCaseSensitiveFileNames: boolean; write(s: string): void; - writeOutputIsTty?(): boolean; + writeOutputIsTTY?(): boolean; readFile(path: string, encoding?: string): string | undefined; getFileSize?(path: string): number; writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; @@ -562,7 +562,7 @@ namespace ts { write(s: string): void { process.stdout.write(s); }, - writeOutputIsTty() { + writeOutputIsTTY() { return process.stdout.isTTY; }, readFile, diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index b2bffd83ca7..3c73eba86ef 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -25,8 +25,8 @@ namespace ts { } function shouldBePretty(options: CompilerOptions) { - if ((typeof options.pretty === "undefined")) { - return !!sys.writeOutputIsTty && sys.writeOutputIsTty(); + if (typeof options.pretty === "undefined") { + return !!sys.writeOutputIsTTY && sys.writeOutputIsTTY(); } return options.pretty; } From 25bb58124bf165354f897a817940cbdbff2c9093 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 18 Apr 2018 12:42:59 -0700 Subject: [PATCH 112/229] Accepted baselines. --- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index dfe2f613078..be11525ffb7 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2888,7 +2888,7 @@ declare namespace ts { newLine: string; useCaseSensitiveFileNames: boolean; write(s: string): void; - writeOutputIsTty?(): boolean; + writeOutputIsTTY?(): boolean; readFile(path: string, encoding?: string): string | undefined; getFileSize?(path: string): number; writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 6963bd95f72..c0cab668854 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2888,7 +2888,7 @@ declare namespace ts { newLine: string; useCaseSensitiveFileNames: boolean; write(s: string): void; - writeOutputIsTty?(): boolean; + writeOutputIsTTY?(): boolean; readFile(path: string, encoding?: string): string | undefined; getFileSize?(path: string): number; writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; From 0e9b815956b0c3d7a110008dd3f1a1ac165259d6 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 18 Apr 2018 12:58:16 -0700 Subject: [PATCH 113/229] Improve performance of duplicate check (#23516) --- src/harness/fourslash.ts | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 8800f78e6fd..75915c915ed 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2103,14 +2103,11 @@ Actual: ${stringify(fullActual)}`); this.raiseError("verifyRangesInImplementationList failed - expected to find at least one implementation location but got 0"); } - for (let i = 0; i < implementations.length; i++) { - for (let j = 0; j < implementations.length; j++) { - if (i !== j && implementationsAreEqual(implementations[i], implementations[j])) { - const { textSpan, fileName } = implementations[i]; - const end = textSpan.start + textSpan.length; - this.raiseError(`Duplicate implementations returned for range (${textSpan.start}, ${end}) in ${fileName}`); - } - } + const duplicate = findDuplicatedElement(implementations, implementationsAreEqual); + if (duplicate) { + const { textSpan, fileName } = duplicate; + const end = textSpan.start + textSpan.length; + this.raiseError(`Duplicate implementations returned for range (${textSpan.start}, ${end}) in ${fileName}`); } const ranges = this.getRanges(); @@ -3756,6 +3753,16 @@ ${code} function stripWhitespace(s: string): string { return s.replace(/\s/g, ""); } + + function findDuplicatedElement(a: ReadonlyArray, equal: (a: T, b: T) => boolean): T { + for (let i = 0; i < a.length; i++) { + for (let j = i + 1; j < a.length; j++) { + if (equal(a[i], a[j])) { + return a[i]; + } + } + } + } } namespace FourSlashInterface { From b271df1639102dc301ef9ab735915cc7eddb91ab Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 18 Apr 2018 12:58:40 -0700 Subject: [PATCH 114/229] Simplify getParentSymbolsOfPropertyAccess (#23513) --- src/services/findAllReferences.ts | 32 +++++++------------------------ 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 268af57e5a3..2812c051bd3 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1030,10 +1030,6 @@ namespace ts.FindAllReferences.Core { } } - function getPropertyAccessExpressionFromRightHandSide(node: Node): PropertyAccessExpression { - return isRightSideOfPropertyAccess(node) && node.parent; - } - /** * `classSymbol` is the class where the constructor was defined. * Reference the constructor and all calls to `new this()`. @@ -1130,18 +1126,6 @@ namespace ts.FindAllReferences.Core { } } - function getSymbolsForClassAndInterfaceComponents(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] { - for (const componentType of type.types) { - if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) { - result.push(componentType.symbol); - } - if (componentType.isUnionOrIntersection()) { - getSymbolsForClassAndInterfaceComponents(componentType, result); - } - } - return result; - } - function getContainingTypeReference(node: Node): Node { let topLevelTypeReference: Node; @@ -1462,7 +1446,7 @@ namespace ts.FindAllReferences.Core { ? rootSymbol && !(getCheckFlags(sym) & CheckFlags.Synthetic) ? rootSymbol : sym : undefined, /*allowBaseTypes*/ rootSymbol => - !(search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker)))); + !(search.parents && !search.parents.some(parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker)))); } /** Gets all symbols for one property. Does not get symbols for every property. */ @@ -1549,13 +1533,11 @@ namespace ts.FindAllReferences.Core { * symbol may have a different parent symbol if the local type's symbol does not declare the property * being accessed (i.e. it is declared in some parent class or interface) */ - function getParentSymbolsOfPropertyAccess(location: Node, symbol: Symbol, checker: TypeChecker): Symbol[] | undefined { - const propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(location); - const localParentType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression); - return localParentType && localParentType.symbol && localParentType.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== symbol.parent - ? [localParentType.symbol] - : localParentType && localParentType.isUnionOrIntersection() - ? getSymbolsForClassAndInterfaceComponents(localParentType) - : undefined; + function getParentSymbolsOfPropertyAccess(location: Node, symbol: Symbol, checker: TypeChecker): ReadonlyArray | undefined { + const propertyAccessExpression = isRightSideOfPropertyAccess(location) ? location.parent : undefined; + const lhsType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression); + const res = mapDefined(lhsType && (lhsType.isUnionOrIntersection() ? lhsType.types : lhsType.symbol === symbol.parent ? undefined : [lhsType]), t => + t.symbol && t.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? t.symbol : undefined); + return res.length === 0 ? undefined : res; } } From 55a3c22d43d5d8c847199acd95de46852ce47c64 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Thu, 19 Apr 2018 05:11:00 +0900 Subject: [PATCH 115/229] Revert "Improve PromiseConstructor" This reverts commit 4318f0d9a0bd17cf4a7c502c3fe57c8538efa5c0. --- src/lib/es2015.promise.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/es2015.promise.d.ts b/src/lib/es2015.promise.d.ts index 65986e85baf..af43abe63d6 100644 --- a/src/lib/es2015.promise.d.ts +++ b/src/lib/es2015.promise.d.ts @@ -10,7 +10,7 @@ interface PromiseConstructor { * a resolve callback used resolve the promise with a value or the result of another promise, * and a reject callback used to reject the promise with a provided reason or error. */ - new (executor: (resolve: [void] extends [T] ? (value?: T | PromiseLike) => void : (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; + new (executor: (resolve: [T] extends [void] ? (value?: T | PromiseLike) => void : (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises From 8f1bdc7e18ec7ffa7ae62571f4d5733dac193470 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 18 Apr 2018 15:24:02 -0700 Subject: [PATCH 116/229] findAllReferences: Reduce node.getSourceFile() calls (#23524) * findAllReferences: Reduce node.getSourceFile() calls * Don't create extra object --- src/services/findAllReferences.ts | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 2812c051bd3..b7baf7166b7 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -130,8 +130,7 @@ namespace ts.FindAllReferences { const { node, name, kind, displayParts } = info; const sourceFile = node.getSourceFile(); - const textSpan = getTextSpan(isComputedPropertyName(node) ? node.expression : node, sourceFile); - return { containerKind: ScriptElementKind.unknown, containerName: "", fileName: sourceFile.fileName, kind, name, textSpan, displayParts }; + return { containerKind: ScriptElementKind.unknown, containerName: "", fileName: sourceFile.fileName, kind, name, textSpan: getTextSpan(isComputedPropertyName(node) ? node.expression : node, sourceFile), displayParts }; } function getDefinitionKindAndDisplayParts(symbol: Symbol, checker: TypeChecker, node: Node): { displayParts: SymbolDisplayPart[], kind: ScriptElementKind } { @@ -148,21 +147,23 @@ namespace ts.FindAllReferences { } const { node, isInString } = entry; + const sourceFile = node.getSourceFile(); return { - fileName: node.getSourceFile().fileName, - textSpan: getTextSpan(node), + fileName: sourceFile.fileName, + textSpan: getTextSpan(node, sourceFile), isWriteAccess: isWriteAccessForReference(node), isDefinition: node.kind === SyntaxKind.DefaultKeyword || isAnyDeclarationName(node) || isLiteralComputedPropertyDeclarationName(node), - isInString + isInString, }; } function toImplementationLocation(entry: Entry, checker: TypeChecker): ImplementationLocation { if (entry.type === "node") { const { node } = entry; - return { textSpan: getTextSpan(node), fileName: node.getSourceFile().fileName, ...implementationKindDisplayParts(node, checker) }; + const sourceFile = node.getSourceFile(); + return { textSpan: getTextSpan(node, sourceFile), fileName: sourceFile.fileName, ...implementationKindDisplayParts(node, checker) }; } else { const { textSpan, fileName } = entry; @@ -199,17 +200,17 @@ namespace ts.FindAllReferences { } const { node, isInString } = entry; - const fileName = entry.node.getSourceFile().fileName; + const sourceFile = node.getSourceFile(); const writeAccess = isWriteAccessForReference(node); const span: HighlightSpan = { - textSpan: getTextSpan(node), + textSpan: getTextSpan(node, sourceFile), kind: writeAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference, isInString }; - return { fileName, span }; + return { fileName: sourceFile.fileName, span }; } - function getTextSpan(node: Node, sourceFile?: SourceFile): TextSpan { + function getTextSpan(node: Node, sourceFile: SourceFile): TextSpan { let start = node.getStart(sourceFile); let end = node.getEnd(); if (node.kind === SyntaxKind.StringLiteral) { From 2f6b59eab9e9e77c133798097b0359e5be009c53 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 18 Apr 2018 15:24:19 -0700 Subject: [PATCH 117/229] Misc. improvements to addImplementationReferences (#23507) * Misc. improvements to addImplementationReferences * Test typeHavingNode.type === typeNode * Fix bug: refNode.parent -> refNode --- src/services/findAllReferences.ts | 60 +++++++++++-------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index b7baf7166b7..60f53c2f527 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1102,57 +1102,37 @@ namespace ts.FindAllReferences.Core { } // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface - const containingTypeReference = getContainingTypeReference(refNode); - if (containingTypeReference && state.markSeenContainingTypeReference(containingTypeReference)) { - const parent = containingTypeReference.parent; - if (hasType(parent) && parent.type === containingTypeReference && hasInitializer(parent) && isImplementationExpression(parent.initializer)) { - addReference(parent.initializer); + // Find the first node whose parent isn't a type node -- i.e., the highest type node. + const typeNode = findAncestor(refNode, a => !isQualifiedName(a.parent) && !isTypeNode(a.parent) && !isTypeElement(a.parent)); + const typeHavingNode = typeNode.parent; + if (hasType(typeHavingNode) && typeHavingNode.type === typeNode && state.markSeenContainingTypeReference(typeHavingNode)) { + if (hasInitializer(typeHavingNode)) { + addIfImplementation(typeHavingNode.initializer); } - else if (isFunctionLike(parent) && parent.type === containingTypeReference && (parent as FunctionLikeDeclaration).body) { - const body = (parent as FunctionLikeDeclaration).body; + else if (isFunctionLike(typeHavingNode) && (typeHavingNode as FunctionLikeDeclaration).body) { + const body = (typeHavingNode as FunctionLikeDeclaration).body; if (body.kind === SyntaxKind.Block) { forEachReturnStatement(body, returnStatement => { - if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { - addReference(returnStatement.expression); - } + if (returnStatement.expression) addIfImplementation(returnStatement.expression); }); } - else if (isImplementationExpression(body)) { - addReference(body); + else { + addIfImplementation(body); } } - else if (isAssertionExpression(parent) && isImplementationExpression(parent.expression)) { - addReference(parent.expression); + else if (isAssertionExpression(typeHavingNode)) { + addIfImplementation(typeHavingNode.expression); } } + + function addIfImplementation(e: Expression): void { + if (isImplementationExpression(e)) addReference(e); + } } - function getContainingTypeReference(node: Node): Node { - let topLevelTypeReference: Node; - - while (node) { - if (isTypeNode(node)) { - topLevelTypeReference = node; - } - node = node.parent; - } - - return topLevelTypeReference; - } - - function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration { - if (node && node.parent) { - if (node.kind === SyntaxKind.ExpressionWithTypeArguments - && node.parent.kind === SyntaxKind.HeritageClause - && isClassLike(node.parent.parent)) { - return node.parent.parent; - } - - else if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) { - return getContainingClassIfInHeritageClause(node.parent); - } - } - return undefined; + function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration | InterfaceDeclaration { + return isIdentifier(node) || isPropertyAccessExpression(node) ? getContainingClassIfInHeritageClause(node.parent) + : isExpressionWithTypeArguments(node) ? tryCast(node.parent.parent, isClassLike) : undefined; } /** From 9e4e215a030d5931dbfcb666352d6226ab742bf7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 18 Apr 2018 15:43:22 -0700 Subject: [PATCH 118/229] Revise IndexType to have stringsOnly property --- src/compiler/checker.ts | 33 +++++++++++++++++---------------- src/compiler/types.ts | 8 ++++---- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 67867074fdb..62b4f537ec6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8191,16 +8191,17 @@ namespace ts { return links.resolvedType; } - function getIndexTypeForGenericType(type: InstantiableType | UnionOrIntersectionType, includeDeclaredTypes?: boolean) { - const cacheLocation = includeDeclaredTypes ? "resolvedDeclaredIndexType" : "resolvedIndexType"; - if (!type[cacheLocation]) { - type[cacheLocation] = createType(TypeFlags.Index); - type[cacheLocation].type = type; - if (includeDeclaredTypes) { - type[cacheLocation].isDeclaredType = true; - } - } - return type[cacheLocation]; + function createIndexType(type: InstantiableType | UnionOrIntersectionType, stringsOnly: boolean) { + const result = createType(TypeFlags.Index); + result.type = type; + result.stringsOnly = stringsOnly; + return result; + } + + function getIndexTypeForGenericType(type: InstantiableType | UnionOrIntersectionType, stringsOnly: boolean) { + return stringsOnly ? + type.resolvedStringIndexType || (type.resolvedStringIndexType = createIndexType(type, /*stringsOnly*/ true)) : + type.resolvedIndexType || (type.resolvedIndexType = createIndexType(type, /*stringsOnly*/ false)); } function getLiteralTypeFromPropertyName(prop: Symbol, include: TypeFlags) { @@ -8225,13 +8226,13 @@ namespace ts { return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined; } - function getIndexType(type: Type, includeDeclaredTypes?: boolean): Type { - return type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, includeDeclaredTypes))) : - maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, includeDeclaredTypes) : + function getIndexType(type: Type, stringsOnly = keyofStringsOnly): Type { + return type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly))) : + maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : type.flags & TypeFlags.Any ? keyofConstraintType : - keyofStringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : + stringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : getLiteralTypeFromPropertyNames(type, TypeFlags.StringOrNumberLiteralOrUnique); @@ -10438,7 +10439,7 @@ namespace ts { // constraint of T. const constraint = getConstraintForRelation((target).type); if (constraint) { - if (result = isRelatedTo(source, getIndexType(constraint, (target as IndexType).isDeclaredType), reportErrors)) { + if (result = isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors)) { return result; } } @@ -21010,7 +21011,7 @@ namespace ts { // Check if the index type is assignable to 'keyof T' for the object type. const objectType = (type).objectType; const indexType = (type).indexType; - if (isTypeAssignableTo(indexType, getIndexType(objectType, /*includeDeclaredTypes*/ true))) { + if (isTypeAssignableTo(indexType, getIndexType(objectType, /*stringsOnly*/ false))) { if (accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) && getObjectFlags(objectType) & ObjectFlags.Mapped && getMappedTypeModifiers(objectType) & MappedTypeModifiers.IncludeReadonly) { error(accessNode, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 894c8d3c8e2..4db1c342098 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3761,7 +3761,7 @@ namespace ts { /* @internal */ resolvedIndexType: IndexType; /* @internal */ - resolvedDeclaredIndexType: IndexType; + resolvedStringIndexType: IndexType; /* @internal */ resolvedBaseConstraint: Type; /* @internal */ @@ -3850,7 +3850,7 @@ namespace ts { /* @internal */ resolvedIndexType?: IndexType; /* @internal */ - resolvedDeclaredIndexType?: IndexType; + resolvedStringIndexType?: IndexType; } // Type parameters (TypeFlags.TypeParameter) @@ -3882,9 +3882,9 @@ namespace ts { // keyof T types (TypeFlags.Index) export interface IndexType extends InstantiableType { - /* @internal */ - isDeclaredType?: boolean; type: InstantiableType | UnionOrIntersectionType; + /* @internal */ + stringsOnly: boolean; } export interface ConditionalRoot { From 5f0d88096c08fbd8dfd0ba25e7c9a2abed833c3b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 18 Apr 2018 15:43:32 -0700 Subject: [PATCH 119/229] Update test --- tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts b/tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts index 09aa9cfdd94..e756b4ef4e0 100644 --- a/tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts +++ b/tests/cases/compiler/lateBoundConstraintTypeChecksCorrectly.ts @@ -1,3 +1,5 @@ +// @keyofStringsOnly: true + declare const fooProp: unique symbol; declare const barProp: unique symbol; From 238ed7a94ca78350294548a164d75624a787e119 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 18 Apr 2018 19:52:34 -0400 Subject: [PATCH 120/229] Visit EOF to collect jsdoc import types (#23521) * Visit EOF to collect jsdoc import types * Add flag to prevent jsdoc import types from influencing compilation set --- src/compiler/program.ts | 6 +++++- .../reference/importTypeResolutionJSDocEOF.symbols | 14 ++++++++++++++ .../reference/importTypeResolutionJSDocEOF.types | 14 ++++++++++++++ .../cases/compiler/importTypeResolutionJSDocEOF.ts | 13 +++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/importTypeResolutionJSDocEOF.symbols create mode 100644 tests/baselines/reference/importTypeResolutionJSDocEOF.types create mode 100644 tests/cases/compiler/importTypeResolutionJSDocEOF.ts diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 514397debc1..9eb82661cf5 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1624,6 +1624,9 @@ namespace ts { collectDynamicImportOrRequireCalls(node); } } + if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) { + collectDynamicImportOrRequireCalls(file.endOfFileToken); + } file.imports = imports || emptyArray; file.moduleAugmentations = moduleAugmentations || emptyArray; @@ -2004,7 +2007,8 @@ namespace ts { && !options.noResolve && i < file.imports.length && !elideImport - && !(isJsFile && !options.allowJs); + && !(isJsFile && !options.allowJs) + && (isInJavaScriptFile(file.imports[i]) || !(file.imports[i].flags & NodeFlags.JSDoc)); if (elideImport) { modulesWithElidedImports.set(file.path, true); diff --git a/tests/baselines/reference/importTypeResolutionJSDocEOF.symbols b/tests/baselines/reference/importTypeResolutionJSDocEOF.symbols new file mode 100644 index 00000000000..35a4695cb76 --- /dev/null +++ b/tests/baselines/reference/importTypeResolutionJSDocEOF.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/interfaces.d.ts === +export interface Bar { +>Bar : Symbol(Bar, Decl(interfaces.d.ts, 0, 0)) + + prop: string +>prop : Symbol(Bar.prop, Decl(interfaces.d.ts, 0, 22)) +} + +=== tests/cases/compiler/usage.js === +/** @type {Bar} */ +export let bar; +>bar : Symbol(bar, Decl(usage.js, 1, 10)) + +/** @typedef {import('./interfaces').Bar} Bar */ diff --git a/tests/baselines/reference/importTypeResolutionJSDocEOF.types b/tests/baselines/reference/importTypeResolutionJSDocEOF.types new file mode 100644 index 00000000000..ecdafddccce --- /dev/null +++ b/tests/baselines/reference/importTypeResolutionJSDocEOF.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/interfaces.d.ts === +export interface Bar { +>Bar : Bar + + prop: string +>prop : string +} + +=== tests/cases/compiler/usage.js === +/** @type {Bar} */ +export let bar; +>bar : Bar + +/** @typedef {import('./interfaces').Bar} Bar */ diff --git a/tests/cases/compiler/importTypeResolutionJSDocEOF.ts b/tests/cases/compiler/importTypeResolutionJSDocEOF.ts new file mode 100644 index 00000000000..a900669e592 --- /dev/null +++ b/tests/cases/compiler/importTypeResolutionJSDocEOF.ts @@ -0,0 +1,13 @@ +// @allowJs: true +// @noEmit: true +// @checkJs: true +// @filename: interfaces.d.ts +export interface Bar { + prop: string +} + +// @filename: usage.js +/** @type {Bar} */ +export let bar; + +/** @typedef {import('./interfaces').Bar} Bar */ \ No newline at end of file From d1b044b72fecb7303336f17efafaba8b70416959 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Wed, 18 Apr 2018 17:08:43 -0700 Subject: [PATCH 121/229] Standardized for --preserveWatchOutput too --- src/compiler/watch.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 330aeaaa840..3140d975a3d 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -50,8 +50,8 @@ namespace ts { Diagnostics.File_change_detected_Starting_incremental_compilation.code, ]; - function getPlainDiagnosticPrecedingNewLines(diagnostic: Diagnostic, newLine: string): string { - return contains(screenStartingMessageCodes, diagnostic.code) + function getPlainDiagnosticPrecedingNewLines(diagnostic: Diagnostic, newLine: string, preserveWatchOutput?: boolean): string { + return !preserveWatchOutput && contains(screenStartingMessageCodes, diagnostic.code) ? "" : newLine; } @@ -75,7 +75,7 @@ namespace ts { } : (diagnostic, newLine, options) => { clearScreenIfNotWatchingForFileChanges(system, diagnostic, options); - let output = `${getPlainDiagnosticPrecedingNewLines(diagnostic, newLine)}${new Date().toLocaleTimeString()} - `; + let output = `${getPlainDiagnosticPrecedingNewLines(diagnostic, newLine, options.preserveWatchOutput)}${new Date().toLocaleTimeString()} - `; output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${getPlainDiagnosticFollowingNewLines(diagnostic, newLine)}`; system.write(output); }; From 2455405b0282cd424875631630074494128eca74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Tue, 30 Jan 2018 19:30:20 +0800 Subject: [PATCH 122/229] allow string concat in enum member declaration --- src/compiler/checker.ts | 15 +++ .../enumConstantMemberWithString.errors.txt | 45 ++++++++ .../reference/enumConstantMemberWithString.js | 64 +++++++++++ .../enumConstantMemberWithString.symbols | 70 ++++++++++++ .../enumConstantMemberWithString.types | 105 ++++++++++++++++++ .../enums/enumConstantMemberWithString.ts | 32 ++++++ 6 files changed, 331 insertions(+) create mode 100644 tests/baselines/reference/enumConstantMemberWithString.errors.txt create mode 100644 tests/baselines/reference/enumConstantMemberWithString.js create mode 100644 tests/baselines/reference/enumConstantMemberWithString.symbols create mode 100644 tests/baselines/reference/enumConstantMemberWithString.types create mode 100644 tests/cases/conformance/enums/enumConstantMemberWithString.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f497ba82e47..4d4e75d3c08 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5277,6 +5277,16 @@ namespace ts { return links.declaredType; } + function isStringConcatExpression(expr: Node): boolean { + if (expr.kind === SyntaxKind.StringLiteral) { + return true; + } + else if (expr.kind === SyntaxKind.BinaryExpression) { + return isStringConcatExpression((expr).left) && isStringConcatExpression((expr).right); + } + return false; + } + function isLiteralEnumMember(member: EnumMember) { const expr = member.initializer; if (!expr) { @@ -5291,6 +5301,8 @@ namespace ts { (expr).operand.kind === SyntaxKind.NumericLiteral; case SyntaxKind.Identifier: return nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports.get((expr).escapedText); + case SyntaxKind.BinaryExpression: + return isStringConcatExpression(expr); default: return false; } @@ -24064,6 +24076,9 @@ namespace ts { case SyntaxKind.AsteriskAsteriskToken: return left ** right; } } + else if (typeof left === "string" && typeof right === "string" && (expr).operatorToken.kind === SyntaxKind.PlusToken) { + return left + right; + } break; case SyntaxKind.StringLiteral: return (expr).text; diff --git a/tests/baselines/reference/enumConstantMemberWithString.errors.txt b/tests/baselines/reference/enumConstantMemberWithString.errors.txt new file mode 100644 index 00000000000..99f089e2bb3 --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithString.errors.txt @@ -0,0 +1,45 @@ +tests/cases/conformance/enums/enumConstantMemberWithString.ts(5,9): error TS2553: Computed values are not permitted in an enum with string valued members. +tests/cases/conformance/enums/enumConstantMemberWithString.ts(6,9): error TS2553: Computed values are not permitted in an enum with string valued members. +tests/cases/conformance/enums/enumConstantMemberWithString.ts(18,9): error TS2553: Computed values are not permitted in an enum with string valued members. + + +==== tests/cases/conformance/enums/enumConstantMemberWithString.ts (3 errors) ==== + enum T1 { + a = "1", + b = "1" + "2", + c = "1" + "2" + "3", + d = "a" - "a", + ~~~~~~~~~ +!!! error TS2553: Computed values are not permitted in an enum with string valued members. + e = "a" + 1 + ~~~~~~~ +!!! error TS2553: Computed values are not permitted in an enum with string valued members. + } + + enum T2 { + a = "1", + b = "1" + "2" + } + + enum T3 { + a = "1", + b = "1" + "2", + c = 1, + d = 1 + 2 + ~~~~~ +!!! error TS2553: Computed values are not permitted in an enum with string valued members. + } + + enum T4 { + a = "1" + } + + enum T5 { + a = "1" + "2" + } + + declare enum T6 { + a = "1", + b = "1" + "2" + } + \ No newline at end of file diff --git a/tests/baselines/reference/enumConstantMemberWithString.js b/tests/baselines/reference/enumConstantMemberWithString.js new file mode 100644 index 00000000000..fc61ed484c8 --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithString.js @@ -0,0 +1,64 @@ +//// [enumConstantMemberWithString.ts] +enum T1 { + a = "1", + b = "1" + "2", + c = "1" + "2" + "3", + d = "a" - "a", + e = "a" + 1 +} + +enum T2 { + a = "1", + b = "1" + "2" +} + +enum T3 { + a = "1", + b = "1" + "2", + c = 1, + d = 1 + 2 +} + +enum T4 { + a = "1" +} + +enum T5 { + a = "1" + "2" +} + +declare enum T6 { + a = "1", + b = "1" + "2" +} + + +//// [enumConstantMemberWithString.js] +var T1; +(function (T1) { + T1["a"] = "1"; + T1["b"] = "12"; + T1["c"] = "123"; + T1[T1["d"] = 0] = "d"; + T1[T1["e"] = 0] = "e"; +})(T1 || (T1 = {})); +var T2; +(function (T2) { + T2["a"] = "1"; + T2["b"] = "12"; +})(T2 || (T2 = {})); +var T3; +(function (T3) { + T3["a"] = "1"; + T3["b"] = "12"; + T3[T3["c"] = 1] = "c"; + T3[T3["d"] = 0] = "d"; +})(T3 || (T3 = {})); +var T4; +(function (T4) { + T4["a"] = "1"; +})(T4 || (T4 = {})); +var T5; +(function (T5) { + T5["a"] = "12"; +})(T5 || (T5 = {})); diff --git a/tests/baselines/reference/enumConstantMemberWithString.symbols b/tests/baselines/reference/enumConstantMemberWithString.symbols new file mode 100644 index 00000000000..625c24fdfef --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithString.symbols @@ -0,0 +1,70 @@ +=== tests/cases/conformance/enums/enumConstantMemberWithString.ts === +enum T1 { +>T1 : Symbol(T1, Decl(enumConstantMemberWithString.ts, 0, 0)) + + a = "1", +>a : Symbol(T1.a, Decl(enumConstantMemberWithString.ts, 0, 9)) + + b = "1" + "2", +>b : Symbol(T1.b, Decl(enumConstantMemberWithString.ts, 1, 12)) + + c = "1" + "2" + "3", +>c : Symbol(T1.c, Decl(enumConstantMemberWithString.ts, 2, 18)) + + d = "a" - "a", +>d : Symbol(T1.d, Decl(enumConstantMemberWithString.ts, 3, 24)) + + e = "a" + 1 +>e : Symbol(T1.e, Decl(enumConstantMemberWithString.ts, 4, 18)) +} + +enum T2 { +>T2 : Symbol(T2, Decl(enumConstantMemberWithString.ts, 6, 1)) + + a = "1", +>a : Symbol(T2.a, Decl(enumConstantMemberWithString.ts, 8, 9)) + + b = "1" + "2" +>b : Symbol(T2.b, Decl(enumConstantMemberWithString.ts, 9, 12)) +} + +enum T3 { +>T3 : Symbol(T3, Decl(enumConstantMemberWithString.ts, 11, 1)) + + a = "1", +>a : Symbol(T3.a, Decl(enumConstantMemberWithString.ts, 13, 9)) + + b = "1" + "2", +>b : Symbol(T3.b, Decl(enumConstantMemberWithString.ts, 14, 12)) + + c = 1, +>c : Symbol(T3.c, Decl(enumConstantMemberWithString.ts, 15, 18)) + + d = 1 + 2 +>d : Symbol(T3.d, Decl(enumConstantMemberWithString.ts, 16, 10)) +} + +enum T4 { +>T4 : Symbol(T4, Decl(enumConstantMemberWithString.ts, 18, 1)) + + a = "1" +>a : Symbol(T4.a, Decl(enumConstantMemberWithString.ts, 20, 9)) +} + +enum T5 { +>T5 : Symbol(T5, Decl(enumConstantMemberWithString.ts, 22, 1)) + + a = "1" + "2" +>a : Symbol(T5.a, Decl(enumConstantMemberWithString.ts, 24, 9)) +} + +declare enum T6 { +>T6 : Symbol(T6, Decl(enumConstantMemberWithString.ts, 26, 1)) + + a = "1", +>a : Symbol(T6.a, Decl(enumConstantMemberWithString.ts, 28, 17)) + + b = "1" + "2" +>b : Symbol(T6.b, Decl(enumConstantMemberWithString.ts, 29, 12)) +} + diff --git a/tests/baselines/reference/enumConstantMemberWithString.types b/tests/baselines/reference/enumConstantMemberWithString.types new file mode 100644 index 00000000000..91bc2f97072 --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithString.types @@ -0,0 +1,105 @@ +=== tests/cases/conformance/enums/enumConstantMemberWithString.ts === +enum T1 { +>T1 : T1 + + a = "1", +>a : T1.a +>"1" : "1" + + b = "1" + "2", +>b : T1.b +>"1" + "2" : string +>"1" : "1" +>"2" : "2" + + c = "1" + "2" + "3", +>c : T1.c +>"1" + "2" + "3" : string +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +>"3" : "3" + + d = "a" - "a", +>d : T1.d +>"a" - "a" : number +>"a" : "a" +>"a" : "a" + + e = "a" + 1 +>e : T1.d +>"a" + 1 : string +>"a" : "a" +>1 : 1 +} + +enum T2 { +>T2 : T2 + + a = "1", +>a : T2.a +>"1" : "1" + + b = "1" + "2" +>b : T2.b +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +} + +enum T3 { +>T3 : T3 + + a = "1", +>a : T3.a +>"1" : "1" + + b = "1" + "2", +>b : T3.b +>"1" + "2" : string +>"1" : "1" +>"2" : "2" + + c = 1, +>c : T3.c +>1 : 1 + + d = 1 + 2 +>d : T3.d +>1 + 2 : number +>1 : 1 +>2 : 2 +} + +enum T4 { +>T4 : T4 + + a = "1" +>a : T4 +>"1" : "1" +} + +enum T5 { +>T5 : T5 + + a = "1" + "2" +>a : T5 +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +} + +declare enum T6 { +>T6 : T6 + + a = "1", +>a : T6.a +>"1" : "1" + + b = "1" + "2" +>b : T6.b +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +} + diff --git a/tests/cases/conformance/enums/enumConstantMemberWithString.ts b/tests/cases/conformance/enums/enumConstantMemberWithString.ts new file mode 100644 index 00000000000..0d2e3a207e2 --- /dev/null +++ b/tests/cases/conformance/enums/enumConstantMemberWithString.ts @@ -0,0 +1,32 @@ +enum T1 { + a = "1", + b = "1" + "2", + c = "1" + "2" + "3", + d = "a" - "a", + e = "a" + 1 +} + +enum T2 { + a = "1", + b = "1" + "2" +} + +enum T3 { + a = "1", + b = "1" + "2", + c = 1, + d = 1 + 2 +} + +enum T4 { + a = "1" +} + +enum T5 { + a = "1" + "2" +} + +declare enum T6 { + a = "1", + b = "1" + "2" +} From b8425fc596b593777003be0fcceea78a3d6b1044 Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 19 Apr 2018 16:10:34 +0000 Subject: [PATCH 123/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index c2b2cf32cde..b6189dcec82 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2388,15 +2388,6 @@ - - - - - - - - - @@ -3771,20 +3762,20 @@ - + - + - + - + - + - + From 557a34e897dbabdcf567cfea343c9443112fdaea Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 19 Apr 2018 10:28:30 -0700 Subject: [PATCH 124/229] Visit typedef type expressions so they contribute to referenced-ness (#23525) --- src/compiler/checker.ts | 6 ++++ .../checkJsTypeDefNoUnusedLocalMarked.symbols | 27 ++++++++++++++++ .../checkJsTypeDefNoUnusedLocalMarked.types | 32 +++++++++++++++++++ .../checkJsTypeDefNoUnusedLocalMarked.ts | 20 ++++++++++++ 4 files changed, 85 insertions(+) create mode 100644 tests/baselines/reference/checkJsTypeDefNoUnusedLocalMarked.symbols create mode 100644 tests/baselines/reference/checkJsTypeDefNoUnusedLocalMarked.types create mode 100644 tests/cases/compiler/checkJsTypeDefNoUnusedLocalMarked.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f497ba82e47..62cff0b1ce5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21865,6 +21865,11 @@ namespace ts { // If the node had `@property` tags, `typeExpression` would have been set to the first property tag. error(node.name, Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags); } + + if (node.name) { + checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0); + } + checkSourceElement(node.typeExpression); } function checkJSDocParameterTag(node: JSDocParameterTag) { @@ -24765,6 +24770,7 @@ namespace ts { case SyntaxKind.JSDocNullableType: case SyntaxKind.JSDocAllType: case SyntaxKind.JSDocUnknownType: + case SyntaxKind.JSDocTypeLiteral: checkJSDocTypeIsInJsFile(node); forEachChild(node, checkSourceElement); return; diff --git a/tests/baselines/reference/checkJsTypeDefNoUnusedLocalMarked.symbols b/tests/baselines/reference/checkJsTypeDefNoUnusedLocalMarked.symbols new file mode 100644 index 00000000000..6826881b834 --- /dev/null +++ b/tests/baselines/reference/checkJsTypeDefNoUnusedLocalMarked.symbols @@ -0,0 +1,27 @@ +=== tests/cases/compiler/file.ts === +class Foo { +>Foo : Symbol(Foo, Decl(file.ts, 0, 0)) + + x: number; +>x : Symbol(Foo.x, Decl(file.ts, 0, 11)) +} + +declare global { +>global : Symbol(global, Decl(file.ts, 2, 1)) + + var module: any; // Just here to remove unrelated error from test +>module : Symbol(module, Decl(file.ts, 5, 7)) +} + +export = Foo; +>Foo : Symbol(Foo, Decl(file.ts, 0, 0)) + +=== tests/cases/compiler/something.js === +/** @typedef {typeof import("./file")} Foo */ + +/** @typedef {(foo: Foo) => string} FooFun */ + +module.exports = /** @type {FooFun} */(void 0); +>module : Symbol(export=, Decl(something.js, 0, 0)) +>exports : Symbol(export=, Decl(something.js, 0, 0)) + diff --git a/tests/baselines/reference/checkJsTypeDefNoUnusedLocalMarked.types b/tests/baselines/reference/checkJsTypeDefNoUnusedLocalMarked.types new file mode 100644 index 00000000000..1428cce142b --- /dev/null +++ b/tests/baselines/reference/checkJsTypeDefNoUnusedLocalMarked.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/file.ts === +class Foo { +>Foo : Foo + + x: number; +>x : number +} + +declare global { +>global : typeof global + + var module: any; // Just here to remove unrelated error from test +>module : any +} + +export = Foo; +>Foo : Foo + +=== tests/cases/compiler/something.js === +/** @typedef {typeof import("./file")} Foo */ + +/** @typedef {(foo: Foo) => string} FooFun */ + +module.exports = /** @type {FooFun} */(void 0); +>module.exports = /** @type {FooFun} */(void 0) : (foo: typeof Foo) => string +>module.exports : any +>module : any +>exports : any +>(void 0) : (foo: typeof Foo) => string +>void 0 : undefined +>0 : 0 + diff --git a/tests/cases/compiler/checkJsTypeDefNoUnusedLocalMarked.ts b/tests/cases/compiler/checkJsTypeDefNoUnusedLocalMarked.ts new file mode 100644 index 00000000000..559e0ee7254 --- /dev/null +++ b/tests/cases/compiler/checkJsTypeDefNoUnusedLocalMarked.ts @@ -0,0 +1,20 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @noUnusedLocals: true +// @filename: file.ts +class Foo { + x: number; +} + +declare global { + var module: any; // Just here to remove unrelated error from test +} + +export = Foo; +// @filename: something.js +/** @typedef {typeof import("./file")} Foo */ + +/** @typedef {(foo: Foo) => string} FooFun */ + +module.exports = /** @type {FooFun} */(void 0); \ No newline at end of file From 8e27f4693cfe1b3e9905e37ffc9c4d37f51c3456 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 19 Apr 2018 10:34:31 -0700 Subject: [PATCH 125/229] Added test for ASI concerns. --- .../templates/taggedTemplatesWithTypeArguments2.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts index 9c9bb8ee938..432e7a21748 100644 --- a/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts +++ b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts @@ -18,3 +18,14 @@ const b = new tag `${"hello"} ${"world"}`(100, 200); const c = new tag `${100} ${200}`("hello", "world"); const d = new tag `${"hello"} ${"world"}`(100, 200); + +/** + * Testing ASI. This should never parse as + * + * ```ts + * new tag; + * `hello${369}`(); + * ``` + */ +const e = new tag +`hello`(); \ No newline at end of file From e21a8b8cfd70cd8709613a4dd4085cc98ad8a46a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 19 Apr 2018 10:34:43 -0700 Subject: [PATCH 126/229] Accepted baselines. --- ...ggedTemplatesWithTypeArguments2.errors.txt | 12 ++++++++++- .../taggedTemplatesWithTypeArguments2.js | 21 ++++++++++++++++++- .../taggedTemplatesWithTypeArguments2.symbols | 13 ++++++++++++ .../taggedTemplatesWithTypeArguments2.types | 17 +++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt index 51b8bd34e0c..9dcc630e71b 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt @@ -27,4 +27,14 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,30 const d = new tag `${"hello"} ${"world"}`(100, 200); ~~~~~~~ !!! error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. - \ No newline at end of file + + /** + * Testing ASI. This should never parse as + * + * ```ts + * new tag; + * `hello${369}`(); + * ``` + */ + const e = new tag + `hello`(); \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js index 33e9fef3d7f..879c274e52f 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js @@ -16,10 +16,29 @@ const b = new tag `${"hello"} ${"world"}`(100, 200); const c = new tag `${100} ${200}`("hello", "world"); const d = new tag `${"hello"} ${"world"}`(100, 200); - + +/** + * Testing ASI. This should never parse as + * + * ```ts + * new tag; + * `hello${369}`(); + * ``` + */ +const e = new tag +`hello`(); //// [taggedTemplatesWithTypeArguments2.js] const a = new tag `${100} ${200}`("hello", "world"); const b = new tag `${"hello"} ${"world"}`(100, 200); const c = (new tag `${100} ${200}`)("hello", "world"); const d = (new tag `${"hello"} ${"world"}`)(100, 200); +/** + * Testing ASI. This should never parse as + * + * ```ts + * new tag; + * `hello${369}`(); + * ``` + */ +const e = new tag `hello`(); diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols index 720b03dd325..049b844bdf2 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols @@ -40,3 +40,16 @@ const d = new tag `${"hello"} ${"world"}`(100, 200); >d : Symbol(d, Decl(taggedTemplatesWithTypeArguments2.ts, 16, 5)) >tag : Symbol(tag, Decl(taggedTemplatesWithTypeArguments2.ts, 8, 13)) +/** + * Testing ASI. This should never parse as + * + * ```ts + * new tag; + * `hello${369}`(); + * ``` + */ +const e = new tag +>e : Symbol(e, Decl(taggedTemplatesWithTypeArguments2.ts, 26, 5)) +>tag : Symbol(tag, Decl(taggedTemplatesWithTypeArguments2.ts, 8, 13)) + +`hello`(); diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types index cd4ff1c6e13..07afb0becc6 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types @@ -70,3 +70,20 @@ const d = new tag `${"hello"} ${"world"}`(100, 200); >100 : 100 >200 : 200 +/** + * Testing ASI. This should never parse as + * + * ```ts + * new tag; + * `hello${369}`(); + * ``` + */ +const e = new tag +>e : any +>new tag`hello`() : any +>tag`hello` : SomethingNewable +>tag : SomethingTaggable + +`hello`(); +>`hello` : "hello" + From 6aab09a82f078fcba1f167edff489d42d4ebed0f Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Thu, 19 Apr 2018 11:42:57 -0700 Subject: [PATCH 127/229] Revert change to PromiseConstructor in #22772 --- src/lib/es2015.promise.d.ts | 2 +- .../reference/defaultExportInAwaitExpression01.types | 6 +++--- .../reference/defaultExportInAwaitExpression02.types | 6 +++--- tests/baselines/reference/inferenceLimit.types | 12 ++++++------ ...dularizeLibrary_NoErrorDuplicateLibOptions1.types | 4 ++-- ...dularizeLibrary_NoErrorDuplicateLibOptions2.types | 4 ++-- .../modularizeLibrary_TargetES5UsingES6Lib.types | 4 ++-- tests/baselines/reference/usePromiseFinally.types | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/lib/es2015.promise.d.ts b/src/lib/es2015.promise.d.ts index 732d8d319c2..14602c0b5ed 100644 --- a/src/lib/es2015.promise.d.ts +++ b/src/lib/es2015.promise.d.ts @@ -10,7 +10,7 @@ interface PromiseConstructor { * a resolve callback used resolve the promise with a value or the result of another promise, * and a reject callback used to reject the promise with a provided reason or error. */ - new (executor: (resolve: [T] extends [void] ? (value?: T | PromiseLike) => void : (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; + new (executor: (resolve: (value?: T | PromiseLike) => void, reject: (reason?: any) => void) => void): Promise; /** * Creates a Promise that is resolved with an array of results when all of the provided Promises diff --git a/tests/baselines/reference/defaultExportInAwaitExpression01.types b/tests/baselines/reference/defaultExportInAwaitExpression01.types index a68e9b88fa2..1f7de76b90e 100644 --- a/tests/baselines/reference/defaultExportInAwaitExpression01.types +++ b/tests/baselines/reference/defaultExportInAwaitExpression01.types @@ -3,11 +3,11 @@ const x = new Promise( ( resolve, reject ) => { resolve( {} ); } ); >x : Promise<{}> >new Promise( ( resolve, reject ) => { resolve( {} ); } ) : Promise<{}> >Promise : PromiseConstructor ->( resolve, reject ) => { resolve( {} ); } : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value: {} | PromiseLike<{}>) => void +>( resolve, reject ) => { resolve( {} ); } : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void >resolve( {} ) : void ->resolve : (value: {} | PromiseLike<{}>) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >{} : {} export default x; diff --git a/tests/baselines/reference/defaultExportInAwaitExpression02.types b/tests/baselines/reference/defaultExportInAwaitExpression02.types index a68e9b88fa2..1f7de76b90e 100644 --- a/tests/baselines/reference/defaultExportInAwaitExpression02.types +++ b/tests/baselines/reference/defaultExportInAwaitExpression02.types @@ -3,11 +3,11 @@ const x = new Promise( ( resolve, reject ) => { resolve( {} ); } ); >x : Promise<{}> >new Promise( ( resolve, reject ) => { resolve( {} ); } ) : Promise<{}> >Promise : PromiseConstructor ->( resolve, reject ) => { resolve( {} ); } : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value: {} | PromiseLike<{}>) => void +>( resolve, reject ) => { resolve( {} ); } : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void >resolve( {} ) : void ->resolve : (value: {} | PromiseLike<{}>) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >{} : {} export default x; diff --git a/tests/baselines/reference/inferenceLimit.types b/tests/baselines/reference/inferenceLimit.types index 16e030241c2..4a398932232 100644 --- a/tests/baselines/reference/inferenceLimit.types +++ b/tests/baselines/reference/inferenceLimit.types @@ -21,8 +21,8 @@ export class BrokenClass { >Array : T[] >MyModule : any >MyModel : MyModule.MyModel ->(resolve, reject) => { let result: Array = []; let populateItems = (order) => { return new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }); }; return Promise.all(result.map(populateItems)) .then((orders: Array) => { resolve(orders); }); } : (resolve: (value: MyModule.MyModel[] | PromiseLike) => void, reject: (reason?: any) => void) => Promise ->resolve : (value: MyModule.MyModel[] | PromiseLike) => void +>(resolve, reject) => { let result: Array = []; let populateItems = (order) => { return new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }); }; return Promise.all(result.map(populateItems)) .then((orders: Array) => { resolve(orders); }); } : (resolve: (value?: MyModule.MyModel[] | PromiseLike) => void, reject: (reason?: any) => void) => Promise +>resolve : (value?: MyModule.MyModel[] | PromiseLike) => void >reject : (reason?: any) => void let result: Array = []; @@ -40,8 +40,8 @@ export class BrokenClass { return new Promise((resolve, reject) => { >new Promise((resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); }) : Promise<{}> >Promise : PromiseConstructor ->(resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); } : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value: {} | PromiseLike<{}>) => void +>(resolve, reject) => { this.doStuff(order.id) .then((items) => { order.items = items; resolve(order); }); } : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void this.doStuff(order.id) @@ -69,7 +69,7 @@ export class BrokenClass { resolve(order); >resolve(order) : void ->resolve : (value: {} | PromiseLike<{}>) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >order : any }); @@ -99,7 +99,7 @@ export class BrokenClass { resolve(orders); >resolve(orders) : void ->resolve : (value: MyModule.MyModel[] | PromiseLike) => void +>resolve : (value?: MyModule.MyModel[] | PromiseLike) => void >orders : MyModule.MyModel[] }); diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types index bda310b20e4..78e6a6bc3f5 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions1.types @@ -138,8 +138,8 @@ async function out() { return new Promise(function (resolve, reject) {}); >new Promise(function (resolve, reject) {}) : Promise<{}> >Promise : PromiseConstructor ->function (resolve, reject) {} : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value: {} | PromiseLike<{}>) => void +>function (resolve, reject) {} : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void } diff --git a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types index 8d05cc40ce4..4aabae824ee 100644 --- a/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types +++ b/tests/baselines/reference/modularizeLibrary_NoErrorDuplicateLibOptions2.types @@ -138,8 +138,8 @@ async function out() { return new Promise(function (resolve, reject) {}); >new Promise(function (resolve, reject) {}) : Promise<{}> >Promise : PromiseConstructor ->function (resolve, reject) {} : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value: {} | PromiseLike<{}>) => void +>function (resolve, reject) {} : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void } diff --git a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types index 9334b118d71..2782c70ebd9 100644 --- a/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types +++ b/tests/baselines/reference/modularizeLibrary_TargetES5UsingES6Lib.types @@ -138,8 +138,8 @@ async function out() { return new Promise(function (resolve, reject) {}); >new Promise(function (resolve, reject) {}) : Promise<{}> >Promise : PromiseConstructor ->function (resolve, reject) {} : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value: {} | PromiseLike<{}>) => void +>function (resolve, reject) {} : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void } diff --git a/tests/baselines/reference/usePromiseFinally.types b/tests/baselines/reference/usePromiseFinally.types index 2dd2d82da79..80534c75610 100644 --- a/tests/baselines/reference/usePromiseFinally.types +++ b/tests/baselines/reference/usePromiseFinally.types @@ -5,8 +5,8 @@ let promise1 = new Promise(function(resolve, reject) {}) >new Promise(function(resolve, reject) {}) .finally : (onfinally?: () => void) => Promise<{}> >new Promise(function(resolve, reject) {}) : Promise<{}> >Promise : PromiseConstructor ->function(resolve, reject) {} : (resolve: (value: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void ->resolve : (value: {} | PromiseLike<{}>) => void +>function(resolve, reject) {} : (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: any) => void) => void +>resolve : (value?: {} | PromiseLike<{}>) => void >reject : (reason?: any) => void .finally(function() {}); From 0f861bbfa87a60e53c001a0bd5add97b1020bcfa Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 19 Apr 2018 22:10:53 +0000 Subject: [PATCH 128/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index f68671fdc91..c53a7b86387 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2388,15 +2388,6 @@ - - - - - - - - - @@ -3771,20 +3762,20 @@ - + - + - + - + - + - + From 7f96fec9d97c88ef95d0aad803db817c8d391e22 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 19 Apr 2018 14:27:48 -0700 Subject: [PATCH 129/229] Added test in case 'super' is ever possibly parsed as a tagged template string. --- .../templates/taggedTemplatesWithTypeArguments2.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts index 432e7a21748..a7a0044d93d 100644 --- a/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts +++ b/tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts @@ -28,4 +28,14 @@ const d = new tag `${"hello"} ${"world"}`(100, 200); * ``` */ const e = new tag -`hello`(); \ No newline at end of file +`hello`(); + +class SomeBase { + a!: A; b!: B; c!: C; +} + +class SomeDerived extends SomeBase { + constructor() { + super `hello world`; + } +} \ No newline at end of file From 70feb7b10ba771a8b137b643046dbb85350cd090 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 19 Apr 2018 14:29:53 -0700 Subject: [PATCH 130/229] Avoid duplicate code when checking for tagged templates. --- src/compiler/checker.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 60fcf103041..b65d153aa45 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17749,15 +17749,11 @@ namespace ts { let typeArguments: NodeArray; - if (isTaggedTemplate) { - typeArguments = (node as TaggedTemplateExpression).typeArguments; - forEach(typeArguments, checkSourceElement); - } - else if (!isDecorator && !isJsxOpeningOrSelfClosingElement) { + if (!isDecorator && !isJsxOpeningOrSelfClosingElement) { typeArguments = (node).typeArguments; // We already perform checking on the type arguments on the class declaration itself. - if ((node).expression.kind !== SyntaxKind.SuperKeyword) { + if (isTaggedTemplate || (node).expression.kind !== SyntaxKind.SuperKeyword) { forEach(typeArguments, checkSourceElement); } } From 87bb96d7b24f6cb27dafddde6de80476d3a4dd5a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 19 Apr 2018 15:15:53 -0700 Subject: [PATCH 131/229] Accepted baselines. --- ...ggedTemplatesWithTypeArguments2.errors.txt | 25 +++++++++++++-- .../taggedTemplatesWithTypeArguments2.js | 19 +++++++++++- .../taggedTemplatesWithTypeArguments2.symbols | 28 +++++++++++++++++ .../taggedTemplatesWithTypeArguments2.types | 31 +++++++++++++++++++ 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt index 9dcc630e71b..44607433031 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt @@ -1,9 +1,12 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,30): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,11): error TS2347: Untyped function calls may not accept type arguments. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,30): error TS2345: Argument of type '"hello"' is not assignable to parameter of type 'number'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(35,5): error TS2377: Constructors for derived classes must contain a 'super' call. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,14): error TS1034: 'super' must be followed by an argument list or member access. -==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (3 errors) ==== +==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (6 errors) ==== export interface SomethingTaggable { (t: TemplateStringsArray, ...args: T[]): SomethingNewable; } @@ -37,4 +40,22 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,30 * ``` */ const e = new tag - `hello`(); \ No newline at end of file + `hello`(); + + class SomeBase { + a!: A; b!: B; c!: C; + } + + class SomeDerived extends SomeBase { + constructor() { + ~~~~~~~~~~~~~~~ + super `hello world`; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~ +!!! error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. + ~ +!!! error TS1034: 'super' must be followed by an argument list or member access. + } + ~~~~~ +!!! error TS2377: Constructors for derived classes must contain a 'super' call. + } \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js index 879c274e52f..bc170467fa8 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js @@ -26,7 +26,17 @@ const d = new tag `${"hello"} ${"world"}`(100, 200); * ``` */ const e = new tag -`hello`(); +`hello`(); + +class SomeBase { + a!: A; b!: B; c!: C; +} + +class SomeDerived extends SomeBase { + constructor() { + super `hello world`; + } +} //// [taggedTemplatesWithTypeArguments2.js] const a = new tag `${100} ${200}`("hello", "world"); @@ -42,3 +52,10 @@ const d = (new tag `${"hello"} ${"world"}`)(100, 200); * ``` */ const e = new tag `hello`(); +class SomeBase { +} +class SomeDerived extends SomeBase { + constructor() { + super. `hello world`; + } +} diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols index 049b844bdf2..631770a30dd 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.symbols @@ -53,3 +53,31 @@ const e = new tag >tag : Symbol(tag, Decl(taggedTemplatesWithTypeArguments2.ts, 8, 13)) `hello`(); + +class SomeBase { +>SomeBase : Symbol(SomeBase, Decl(taggedTemplatesWithTypeArguments2.ts, 27, 10)) +>A : Symbol(A, Decl(taggedTemplatesWithTypeArguments2.ts, 29, 15)) +>B : Symbol(B, Decl(taggedTemplatesWithTypeArguments2.ts, 29, 17)) +>C : Symbol(C, Decl(taggedTemplatesWithTypeArguments2.ts, 29, 20)) + + a!: A; b!: B; c!: C; +>a : Symbol(SomeBase.a, Decl(taggedTemplatesWithTypeArguments2.ts, 29, 25)) +>A : Symbol(A, Decl(taggedTemplatesWithTypeArguments2.ts, 29, 15)) +>b : Symbol(SomeBase.b, Decl(taggedTemplatesWithTypeArguments2.ts, 30, 10)) +>B : Symbol(B, Decl(taggedTemplatesWithTypeArguments2.ts, 29, 17)) +>c : Symbol(SomeBase.c, Decl(taggedTemplatesWithTypeArguments2.ts, 30, 17)) +>C : Symbol(C, Decl(taggedTemplatesWithTypeArguments2.ts, 29, 20)) +} + +class SomeDerived extends SomeBase { +>SomeDerived : Symbol(SomeDerived, Decl(taggedTemplatesWithTypeArguments2.ts, 31, 1)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments2.ts, 33, 18)) +>SomeBase : Symbol(SomeBase, Decl(taggedTemplatesWithTypeArguments2.ts, 27, 10)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments2.ts, 33, 18)) + + constructor() { + super `hello world`; +>super : Symbol(SomeBase, Decl(taggedTemplatesWithTypeArguments2.ts, 27, 10)) +>T : Symbol(T, Decl(taggedTemplatesWithTypeArguments2.ts, 33, 18)) + } +} diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types index 07afb0becc6..8aef2009d1b 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types @@ -87,3 +87,34 @@ const e = new tag `hello`(); >`hello` : "hello" +class SomeBase { +>SomeBase : SomeBase +>A : A +>B : B +>C : C + + a!: A; b!: B; c!: C; +>a : A +>A : A +>b : B +>B : B +>c : C +>C : C +} + +class SomeDerived extends SomeBase { +>SomeDerived : SomeDerived +>T : T +>SomeBase : SomeBase +>T : T + + constructor() { + super `hello world`; +>super `hello world` : any +>super : any +>super : SomeBase +> : any +>T : T +>`hello world` : "hello world" + } +} From bc7979c1743f946f5366ca2893d1bd4c50633d8d Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 19 Apr 2018 15:33:36 -0700 Subject: [PATCH 132/229] quickInfo: Get JSDoc tags from aliased symbol (#23526) * quickInfo: Get JSDoc tags from aliased symbol * Add test with existing tags --- src/services/symbolDisplay.ts | 5 +++ tests/cases/fourslash/fourslash.ts | 2 +- tests/cases/fourslash/quickInfoAlias.ts | 51 +++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/quickInfoAlias.ts diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index f79c048efad..7abb89befd7 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -134,6 +134,7 @@ namespace ts.SymbolDisplay { let type: Type; let printer: Printer; let documentationFromAlias: SymbolDisplayPart[]; + let tagsFromAlias: JSDocTagInfo[]; // Class at constructor site need to be shown as constructor apart from property,method, vars if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Alias) { @@ -396,6 +397,7 @@ namespace ts.SymbolDisplay { displayParts.push(...resolvedInfo.displayParts); displayParts.push(lineBreakPart()); documentationFromAlias = resolvedInfo.documentation; + tagsFromAlias = resolvedInfo.tags; } } } @@ -521,6 +523,9 @@ namespace ts.SymbolDisplay { if (documentation.length === 0 && documentationFromAlias) { documentation = documentationFromAlias; } + if (tags.length === 0 && tagsFromAlias) { + tags = tagsFromAlias; + } return { displayParts, documentation, symbolKind, tags }; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index e756bd22fae..697d2d72555 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -338,7 +338,7 @@ declare namespace FourSlashInterface { verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: { start: number; length: number; - }, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[]): void; + }, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: { name: string, text?: string }[]): void; getSyntacticDiagnostics(expected: ReadonlyArray): void; getSemanticDiagnostics(expected: ReadonlyArray): void; getSuggestionDiagnostics(expected: ReadonlyArray): void; diff --git a/tests/cases/fourslash/quickInfoAlias.ts b/tests/cases/fourslash/quickInfoAlias.ts new file mode 100644 index 00000000000..cfbe8ed3692 --- /dev/null +++ b/tests/cases/fourslash/quickInfoAlias.ts @@ -0,0 +1,51 @@ +/// + +// @Filename: /a.ts +/////** +//// * Doc +//// * @tag Tag text +//// */ +////export const x = 0; + +// @Filename: /b.ts +////import { x } from "./a"; +////x/*b*/; + +// @Filename: /c.ts +/////** +//// * Doc 2 +//// * @tag Tag text 2 +//// */ +////import { +//// /** +//// * Doc 3 +//// * @tag Tag text 3 +//// */ +//// x +////} from "./a"; +////x/*c*/; + +goTo.eachMarker((_, index) => { + verify.verifyQuickInfoDisplayParts( + "alias", + "", + { start: index === 0 ? 25 : 117, length: 1 }, + [ + { text:"(",kind:"punctuation" }, + { text:"alias",kind:"text" }, + { text:")",kind:"punctuation" }, + { text:" ",kind:"space" }, + { text:"const",kind:"keyword" }, + { text:" ",kind:"space" }, + { text:"x",kind:"aliasName" }, + { text:":",kind:"punctuation" }, + { text:" ",kind:"space" }, + { text:"0",kind:"stringLiteral" }, + { text:"\n",kind:"lineBreak" }, + { text:"import",kind:"keyword" }, + { text:" ",kind:"space" }, + { text:"x",kind:"aliasName" }, + ], + [{ text: "Doc", kind: "text" }], + [{ name: "tag", text: "Tag text" }]); +}); From c258d6e1b65f5a0e66bac07ed61b6845baf536f1 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 19 Apr 2018 15:35:25 -0700 Subject: [PATCH 133/229] Fix bug: Don't rename 'default' in `export { default as x } from "m";` (#23434) * Fix bug: Don't rename 'default' in `export { default as x } from "m";` * Rename `foo` in `{ default as foo }` if that's the original export name --- src/services/findAllReferences.ts | 10 ++++++++-- src/services/importTracker.ts | 6 ++++-- .../findAllRefsRenameImportWithSameName.ts | 5 +++-- .../cases/fourslash/renameReExportDefault.ts | 19 +++++++++++++++++++ 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 tests/cases/fourslash/renameReExportDefault.ts diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 60f53c2f527..57fe2a7a0e4 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -555,7 +555,10 @@ namespace ts.FindAllReferences.Core { if (singleReferences.length) { const addRef = state.referenceAdder(exportSymbol); for (const singleRef of singleReferences) { - addRef(singleRef); + // At `default` in `import { default as x }` or `export { default as x }`, do add a reference, but do not rename. + if (!(state.options.isForRename && (isExportSpecifier(singleRef.parent) || isImportSpecifier(singleRef.parent)) && singleRef.escapedText === InternalSymbolName.Default)) { + addRef(singleRef); + } } } @@ -887,7 +890,10 @@ namespace ts.FindAllReferences.Core { } if (!propertyName) { - addRef(); + // Don't rename at `export { default } from "m";`. (but do continue to search for imports of the re-export) + if (!(state.options.isForRename && name.escapedText === InternalSymbolName.Default)) { + addRef(); + } } else if (referenceLocation === propertyName) { // For `export { foo as bar } from "baz"`, "`foo`" will be added from the singleReferences for import searches of the original export. diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 80f0721e642..1a4b2a9f751 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -254,7 +254,7 @@ namespace ts.FindAllReferences { } // 'default' might be accessed as a named import `{ default as foo }`. - if (!isForRename && exportKind === ExportKind.Default) { + if (exportKind === ExportKind.Default) { searchForNamedImport(namedBindings as NamedImports | undefined); } } @@ -286,7 +286,9 @@ namespace ts.FindAllReferences { if (propertyName) { // This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference. singleReferences.push(propertyName); - if (!isForRename) { // If renaming `foo`, don't touch `bar`, just `foo`. + // If renaming `{ foo as bar }`, don't touch `bar`, just `foo`. + // But do rename `foo` in ` { default as foo }` if that's the original export name. + if (!isForRename || name.escapedText === exportSymbol.escapedName) { // Search locally for `bar`. addSearch(name, checker.getSymbolAtLocation(name)); } diff --git a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts index 62b1c19c5ed..38c3aaf9398 100644 --- a/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts +++ b/tests/cases/fourslash/findAllRefsRenameImportWithSameName.ts @@ -16,5 +16,6 @@ const bGroup = { definition: "(alias) const x: 0\nimport x", ranges: bRanges }; verify.referenceGroups(aRanges, [aGroup, bGroup]); verify.referenceGroups(bRanges, [bGroup]); -verify.rangesAreRenameLocations(aRanges); -verify.rangesAreRenameLocations(aRanges); +verify.renameLocations(r0, [r0, r1, r2, r3]); +verify.renameLocations(r1, [r0, r1, r2, r3]); +verify.rangesAreRenameLocations([r2, r3]); diff --git a/tests/cases/fourslash/renameReExportDefault.ts b/tests/cases/fourslash/renameReExportDefault.ts new file mode 100644 index 00000000000..0eb5b81d209 --- /dev/null +++ b/tests/cases/fourslash/renameReExportDefault.ts @@ -0,0 +1,19 @@ +/// + +// @Filename: /a.ts +////export { default } from "./b"; +////export { default as [|b|] } from "./b"; +////export { default as bee } from "./b"; +////import { default as [|b|] } from "./b"; +////import { default as bee } from "./b"; +////import [|b|] from "./b"; + +// @Filename: /b.ts +////const [|b|] = 0; +////export default [|b|]; + +const [r0, r1, r2, r3, r4] = test.ranges(); +verify.renameLocations(r0, [r0]); +verify.renameLocations(r1, [r1]); +verify.renameLocations(r2, [r2]); +verify.renameLocations([r3, r4], [r0, r1, r2, r3, r4]); From a7c08e4691584e6d2fac55b3dccdd88936ecda6a Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 19 Apr 2018 15:39:44 -0700 Subject: [PATCH 134/229] Make code fix to add 'this.' work for statics (#23527) * Make code fix to add 'this.' work for statics * Add 'C.' instead of 'this.' * DanielRosenwasser code review --- src/compiler/diagnosticMessages.json | 4 +-- .../fixForgottenThisPropertyAccess.ts | 31 ++++++++++--------- .../codeFixForgottenThisPropertyAccess_all.ts | 2 +- ...deFixForgottenThisPropertyAccess_static.ts | 25 +++++++++++++++ 4 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 tests/cases/fourslash/codeFixForgottenThisPropertyAccess_static.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 235788258af..a5119f7feb7 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3914,7 +3914,7 @@ "category": "Message", "code": 90007 }, - "Add 'this.' to unresolved variable": { + "Add '{0}.' to unresolved variable": { "category": "Message", "code": 90008 }, @@ -4122,7 +4122,7 @@ "category": "Message", "code": 95036 }, - "Add 'this.' to all unresolved variables matching a member name": { + "Add qualifier to all unresolved variables matching a member name": { "category": "Message", "code": 95037 }, diff --git a/src/services/codefixes/fixForgottenThisPropertyAccess.ts b/src/services/codefixes/fixForgottenThisPropertyAccess.ts index b26e4c7cdca..31c6128d003 100644 --- a/src/services/codefixes/fixForgottenThisPropertyAccess.ts +++ b/src/services/codefixes/fixForgottenThisPropertyAccess.ts @@ -1,35 +1,38 @@ /* @internal */ namespace ts.codefix { const fixId = "forgottenThisPropertyAccess"; - const errorCodes = [Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code]; + const didYouMeanStaticMemberCode = Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code; + const errorCodes = [ + Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code, + didYouMeanStaticMemberCode, + ]; registerCodeFix({ errorCodes, getCodeActions(context) { const { sourceFile } = context; - const token = getNode(sourceFile, context.span.start); - if (!token) { + const info = getInfo(sourceFile, context.span.start, context.errorCode); + if (!info) { return undefined; } - const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, token)); - return [createCodeFixAction(fixId, changes, Diagnostics.Add_this_to_unresolved_variable, fixId, Diagnostics.Add_this_to_all_unresolved_variables_matching_a_member_name)]; + const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info)); + return [createCodeFixAction(fixId, changes, [Diagnostics.Add_0_to_unresolved_variable, info.className || "this"], fixId, Diagnostics.Add_qualifier_to_all_unresolved_variables_matching_a_member_name)]; }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => { - doChange(changes, context.sourceFile, getNode(diag.file, diag.start!)); + doChange(changes, context.sourceFile, getInfo(diag.file, diag.start!, diag.code)); }), }); - function getNode(sourceFile: SourceFile, pos: number): Identifier | undefined { + interface Info { readonly node: Identifier; readonly className: string | undefined; } + function getInfo(sourceFile: SourceFile, pos: number, diagCode: number): Info | undefined { const node = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false); - return isIdentifier(node) ? node : undefined; + if (!isIdentifier(node)) return undefined; + return { node, className: diagCode === didYouMeanStaticMemberCode ? getContainingClass(node).name.text : undefined }; } - function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Identifier | undefined): void { - if (!token) { - return; - } + function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { node, className }: Info): void { // TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper - suppressLeadingAndTrailingTrivia(token); - changes.replaceNode(sourceFile, token, createPropertyAccess(createThis(), token)); + suppressLeadingAndTrailingTrivia(node); + changes.replaceNode(sourceFile, node, createPropertyAccess(className ? createIdentifier(className) : createThis(), node)); } } diff --git a/tests/cases/fourslash/codeFixForgottenThisPropertyAccess_all.ts b/tests/cases/fourslash/codeFixForgottenThisPropertyAccess_all.ts index ab95f6b3355..65d44dd8fdb 100644 --- a/tests/cases/fourslash/codeFixForgottenThisPropertyAccess_all.ts +++ b/tests/cases/fourslash/codeFixForgottenThisPropertyAccess_all.ts @@ -10,7 +10,7 @@ verify.codeFixAll({ fixId: "forgottenThisPropertyAccess", - fixAllDescription: "Add 'this.' to all unresolved variables matching a member name", + fixAllDescription: "Add qualifier to all unresolved variables matching a member name", newFileContent: `class C { foo: number; diff --git a/tests/cases/fourslash/codeFixForgottenThisPropertyAccess_static.ts b/tests/cases/fourslash/codeFixForgottenThisPropertyAccess_static.ts new file mode 100644 index 00000000000..cc6f8032a51 --- /dev/null +++ b/tests/cases/fourslash/codeFixForgottenThisPropertyAccess_static.ts @@ -0,0 +1,25 @@ +/// + +////class C { +//// static m() { m(); } +//// n() { m(); } +////} + +verify.codeFix({ + description: "Add 'C.' to unresolved variable", + index: 0, + newFileContent: +`class C { + static m() { C.m(); } + n() { m(); } +}` +}); + +verify.codeFix({ + description: "Add 'C.' to unresolved variable", + newFileContent: +`class C { + static m() { C.m(); } + n() { C.m(); } +}` +}); From 8d969a23cba2cec9ce3baa5e1cfaafda2c7c0301 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 19 Apr 2018 15:58:43 -0700 Subject: [PATCH 135/229] In JS, class supports `@template` tag for declaring type parameters (#23511) * Support @template as a class type parameter Still need to do the following: 1. Correctly get jsdoc host in predicate. 2. Make this work for constructor functions too. 3. Scan rest of codebase for other usages of the type parameters property that should be calls to getEffectiveTypeParameterDeclarations. 4. Rename tp to something more readable, like typar or ts'. * Use jsdoc host declaration to find container * Longer names for type parameters * Fix renaming operation * Update fourslash test * Support @template for JS constructors * Look for both outer and tag type parameters * Improve naming to improve code clarity --- src/compiler/checker.ts | 72 +++++++++++------- src/compiler/utilities.ts | 4 +- .../reference/jsdocTemplateClass.errors.txt | 31 ++++++++ .../reference/jsdocTemplateClass.symbols | 54 +++++++++++++ .../reference/jsdocTemplateClass.types | 62 +++++++++++++++ ...sdocTemplateConstructorFunction.errors.txt | 28 +++++++ .../jsdocTemplateConstructorFunction.symbols | 57 ++++++++++++++ .../jsdocTemplateConstructorFunction.types | 76 +++++++++++++++++++ .../conformance/jsdoc/jsdocTemplateClass.ts | 29 +++++++ .../jsdoc/jsdocTemplateConstructorFunction.ts | 26 +++++++ .../findAllRefsJsDocTemplateTag_class_js.ts | 5 +- 11 files changed, 413 insertions(+), 31 deletions(-) create mode 100644 tests/baselines/reference/jsdocTemplateClass.errors.txt create mode 100644 tests/baselines/reference/jsdocTemplateClass.symbols create mode 100644 tests/baselines/reference/jsdocTemplateClass.types create mode 100644 tests/baselines/reference/jsdocTemplateConstructorFunction.errors.txt create mode 100644 tests/baselines/reference/jsdocTemplateConstructorFunction.symbols create mode 100644 tests/baselines/reference/jsdocTemplateConstructorFunction.types create mode 100644 tests/cases/conformance/jsdoc/jsdocTemplateClass.ts create mode 100644 tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6c8a79daf5f..bfc9c1fd550 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1554,7 +1554,8 @@ namespace ts { function isTypeParameterSymbolDeclaredInContainer(symbol: Symbol, container: Node) { for (const decl of symbol.declarations) { - if (decl.kind === SyntaxKind.TypeParameter && decl.parent === container) { + const parent = isJSDocTemplateTag(decl.parent) ? getJSDocHost(decl.parent) : decl.parent; + if (decl.kind === SyntaxKind.TypeParameter && parent === container) { return true; } } @@ -2060,10 +2061,10 @@ namespace ts { let symbol: Symbol; if (name.kind === SyntaxKind.Identifier) { const message = meaning === namespaceMeaning ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0; - - symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors ? undefined : message, name, /*isUse*/ true); + const symbolFromJSPrototype = isInJavaScriptFile(name) && resolveEntityNameFromJSPrototype(name, meaning); + symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true); if (!symbol) { - return undefined; + return symbolFromJSPrototype; } } else if (name.kind === SyntaxKind.QualifiedName || name.kind === SyntaxKind.PropertyAccessExpression) { @@ -2114,6 +2115,18 @@ namespace ts { return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol); } + function resolveEntityNameFromJSPrototype(name: Identifier, meaning: SymbolFlags) { + if (isJSDocTypeReference(name.parent) && isJSDocTag(name.parent.parent.parent)) { + const host = getJSDocHost(name.parent.parent.parent as JSDocTag); + if (isExpressionStatement(host) && + isBinaryExpression(host.expression) && + getSpecialPropertyAssignmentKind(host.expression) === SpecialPropertyAssignmentKind.PrototypeProperty) { + const secondaryLocation = getSymbolOfNode(host.expression.left).parent.valueDeclaration; + return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true); + } + } + } + function resolveExternalModuleName(location: Node, moduleReferenceExpression: Expression): Symbol { return resolveExternalModuleNameWorker(location, moduleReferenceExpression, Diagnostics.Cannot_find_module_0); } @@ -4897,8 +4910,7 @@ namespace ts { // in-place and returns the same array. function appendTypeParameters(typeParameters: TypeParameter[], declarations: ReadonlyArray): TypeParameter[] { for (const declaration of declarations) { - const tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); - typeParameters = appendIfUnique(typeParameters, tp); + typeParameters = appendIfUnique(typeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration))); } return typeParameters; } @@ -4958,8 +4970,9 @@ namespace ts { if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.TypeAliasDeclaration) { const declaration = node; - if (declaration.typeParameters) { - result = appendTypeParameters(result, declaration.typeParameters); + const typeParameters = getEffectiveTypeParameterDeclarations(declaration); + if (typeParameters) { + result = appendTypeParameters(result, typeParameters); } } } @@ -5455,9 +5468,10 @@ namespace ts { */ function isThislessFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean { const returnType = getEffectiveReturnTypeNode(node); + const typeParameters = getEffectiveTypeParameterDeclarations(node); return (node.kind === SyntaxKind.Constructor || (returnType && isThislessType(returnType))) && node.parameters.every(isThislessVariableLikeDeclaration) && - (!node.typeParameters || node.typeParameters.every(isThislessTypeParameter)); + (!typeParameters || typeParameters.every(isThislessTypeParameter)); } /** @@ -6735,8 +6749,7 @@ namespace ts { function getTypeParametersFromDeclaration(declaration: DeclarationWithTypeParameters): TypeParameter[] { let result: TypeParameter[]; forEach(getEffectiveTypeParameterDeclarations(declaration), node => { - const tp = getDeclaredTypeOfTypeParameter(node.symbol); - result = appendIfUnique(result, tp); + result = appendIfUnique(result, getDeclaredTypeOfTypeParameter(node.symbol)); }); return result; } @@ -7547,7 +7560,7 @@ namespace ts { return constraints ? getSubstitutionType(typeVariable, getIntersectionType(append(constraints, typeVariable))) : typeVariable; } - function isJSDocTypeReference(node: NodeWithTypeArguments): node is TypeReferenceNode { + function isJSDocTypeReference(node: Node): node is TypeReferenceNode { return node.flags & NodeFlags.JSDoc && node.kind === SyntaxKind.TypeReference; } @@ -9170,10 +9183,15 @@ namespace ts { // aren't the right hand side of a generic type alias declaration we optimize by reducing the // set of type parameters to those that are possibly referenced in the literal. const declaration = symbol.declarations[0]; - const outerTypeParameters = getOuterTypeParameters(declaration, /*includeThisTypes*/ true) || emptyArray; + let outerTypeParameters = getOuterTypeParameters(declaration, /*includeThisTypes*/ true); + if (isJavaScriptConstructor(declaration)) { + const templateTagParameters = getTypeParametersFromDeclaration(declaration as DeclarationWithTypeParameters); + outerTypeParameters = addRange(outerTypeParameters, templateTagParameters); + } + typeParameters = outerTypeParameters || emptyArray; typeParameters = symbol.flags & SymbolFlags.TypeLiteral && !target.aliasTypeArguments ? - filter(outerTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, declaration)) : - outerTypeParameters; + filter(typeParameters, tp => isTypeParameterPossiblyReferenced(tp, declaration)) : + typeParameters; links.outerTypeParameters = typeParameters; if (typeParameters.length) { links.instantiations = createMap(); @@ -18533,7 +18551,7 @@ namespace ts { } const type = funcSymbol && getJavaScriptClassType(funcSymbol); if (type) { - return type; + return signature.target ? instantiateType(type, signature.mapper) : type; } if (noImplicitAny) { error(node, Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); @@ -22161,8 +22179,9 @@ namespace ts { ): void { // Only report errors on the last declaration for the type parameter container; // this ensures that all uses have been accounted for. - if (!(node.flags & NodeFlags.Ambient) && node.typeParameters && last(getSymbolOfNode(node)!.declarations) === node) { - for (const typeParameter of node.typeParameters) { + const typeParameters = getEffectiveTypeParameterDeclarations(node); + if (!(node.flags & NodeFlags.Ambient) && typeParameters && last(getSymbolOfNode(node)!.declarations) === node) { + for (const typeParameter of typeParameters) { if (!(getMergedSymbol(typeParameter.symbol).isReferenced & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) { addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol))); } @@ -23536,20 +23555,21 @@ namespace ts { } } - function areTypeParametersIdentical(declarations: ReadonlyArray, typeParameters: TypeParameter[]) { - const maxTypeArgumentCount = length(typeParameters); - const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); + function areTypeParametersIdentical(declarations: ReadonlyArray, targetParameters: TypeParameter[]) { + const maxTypeArgumentCount = length(targetParameters); + const minTypeArgumentCount = getMinTypeArgumentCount(targetParameters); for (const declaration of declarations) { // If this declaration has too few or too many type parameters, we report an error - const numTypeParameters = length(declaration.typeParameters); + const sourceParameters = getEffectiveTypeParameterDeclarations(declaration); + const numTypeParameters = length(sourceParameters); if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) { return false; } for (let i = 0; i < numTypeParameters; i++) { - const source = declaration.typeParameters[i]; - const target = typeParameters[i]; + const source = sourceParameters[i]; + const target = targetParameters[i]; // If the type parameter node does not have the same as the resolved type // parameter at this position, we report an error. @@ -23610,7 +23630,7 @@ namespace ts { checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } - checkTypeParameters(node.typeParameters); + checkTypeParameters(getEffectiveTypeParameterDeclarations(node)); checkExportsOnMergedDeclarations(node); const symbol = getSymbolOfNode(node); const type = getDeclaredTypeOfSymbol(symbol); @@ -26846,7 +26866,7 @@ namespace ts { function checkGrammarClassLikeDeclaration(node: ClassLikeDeclaration): boolean { const file = getSourceFileOfNode(node); - return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file); + return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(getEffectiveTypeParameterDeclarations(node), file); } function checkGrammarArrowFunction(node: Node, file: SourceFile): boolean { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3fe255fb612..730c3fc51d4 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3055,11 +3055,11 @@ namespace ts { * Gets the effective type parameters. If the node was parsed in a * JavaScript file, gets the type parameters from the `@template` tag from JSDoc. */ - export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray | undefined { + export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters) { return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : undefined); } - export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray { + export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters) { const templateTag = getJSDocTemplateTag(node); return templateTag && templateTag.typeParameters; } diff --git a/tests/baselines/reference/jsdocTemplateClass.errors.txt b/tests/baselines/reference/jsdocTemplateClass.errors.txt new file mode 100644 index 00000000000..4598e9f320f --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateClass.errors.txt @@ -0,0 +1,31 @@ +tests/cases/conformance/jsdoc/templateTagOnClasses.js(24,1): error TS2322: Type 'boolean' is not assignable to type 'number'. + + +==== tests/cases/conformance/jsdoc/templateTagOnClasses.js (1 errors) ==== + /** + * @template {T} + * @typedef {(t: T) => T} Id + */ + class Foo { + /** @typedef {(t: T) => T} Id2 */ + /** @param {T} x */ + constructor (x) { + this.a = x + } + /** + * + * @param {T} x + * @param {Id} y + * @param {Id2} alpha + * @return {T} + */ + foo(x, y, alpha) { + return alpha(y(x)) + } + } + var f = new Foo(1) + var g = new Foo(false) + f.a = g.a + ~~~ +!!! error TS2322: Type 'boolean' is not assignable to type 'number'. + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocTemplateClass.symbols b/tests/baselines/reference/jsdocTemplateClass.symbols new file mode 100644 index 00000000000..d80b73bc4ac --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateClass.symbols @@ -0,0 +1,54 @@ +=== tests/cases/conformance/jsdoc/templateTagOnClasses.js === +/** + * @template {T} + * @typedef {(t: T) => T} Id + */ +class Foo { +>Foo : Symbol(Foo, Decl(templateTagOnClasses.js, 0, 0)) + + /** @typedef {(t: T) => T} Id2 */ + /** @param {T} x */ + constructor (x) { +>x : Symbol(x, Decl(templateTagOnClasses.js, 7, 17)) + + this.a = x +>this.a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 7, 21)) +>this : Symbol(Foo, Decl(templateTagOnClasses.js, 0, 0)) +>a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 7, 21)) +>x : Symbol(x, Decl(templateTagOnClasses.js, 7, 17)) + } + /** + * + * @param {T} x + * @param {Id} y + * @param {Id2} alpha + * @return {T} + */ + foo(x, y, alpha) { +>foo : Symbol(Foo.foo, Decl(templateTagOnClasses.js, 9, 5)) +>x : Symbol(x, Decl(templateTagOnClasses.js, 17, 8)) +>y : Symbol(y, Decl(templateTagOnClasses.js, 17, 10)) +>alpha : Symbol(alpha, Decl(templateTagOnClasses.js, 17, 13)) + + return alpha(y(x)) +>alpha : Symbol(alpha, Decl(templateTagOnClasses.js, 17, 13)) +>y : Symbol(y, Decl(templateTagOnClasses.js, 17, 10)) +>x : Symbol(x, Decl(templateTagOnClasses.js, 17, 8)) + } +} +var f = new Foo(1) +>f : Symbol(f, Decl(templateTagOnClasses.js, 21, 3)) +>Foo : Symbol(Foo, Decl(templateTagOnClasses.js, 0, 0)) + +var g = new Foo(false) +>g : Symbol(g, Decl(templateTagOnClasses.js, 22, 3)) +>Foo : Symbol(Foo, Decl(templateTagOnClasses.js, 0, 0)) + +f.a = g.a +>f.a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 7, 21)) +>f : Symbol(f, Decl(templateTagOnClasses.js, 21, 3)) +>a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 7, 21)) +>g.a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 7, 21)) +>g : Symbol(g, Decl(templateTagOnClasses.js, 22, 3)) +>a : Symbol(Foo.a, Decl(templateTagOnClasses.js, 7, 21)) + diff --git a/tests/baselines/reference/jsdocTemplateClass.types b/tests/baselines/reference/jsdocTemplateClass.types new file mode 100644 index 00000000000..aa6a685e34f --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateClass.types @@ -0,0 +1,62 @@ +=== tests/cases/conformance/jsdoc/templateTagOnClasses.js === +/** + * @template {T} + * @typedef {(t: T) => T} Id + */ +class Foo { +>Foo : Foo + + /** @typedef {(t: T) => T} Id2 */ + /** @param {T} x */ + constructor (x) { +>x : T + + this.a = x +>this.a = x : T +>this.a : T +>this : this +>a : T +>x : T + } + /** + * + * @param {T} x + * @param {Id} y + * @param {Id2} alpha + * @return {T} + */ + foo(x, y, alpha) { +>foo : (x: T, y: (t: T) => T, alpha: (t: T) => T) => T +>x : T +>y : (t: T) => T +>alpha : (t: T) => T + + return alpha(y(x)) +>alpha(y(x)) : T +>alpha : (t: T) => T +>y(x) : T +>y : (t: T) => T +>x : T + } +} +var f = new Foo(1) +>f : Foo +>new Foo(1) : Foo +>Foo : typeof Foo +>1 : 1 + +var g = new Foo(false) +>g : Foo +>new Foo(false) : Foo +>Foo : typeof Foo +>false : false + +f.a = g.a +>f.a = g.a : boolean +>f.a : number +>f : Foo +>a : number +>g.a : boolean +>g : Foo +>a : boolean + diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction.errors.txt b/tests/baselines/reference/jsdocTemplateConstructorFunction.errors.txt new file mode 100644 index 00000000000..225d277c4ff --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction.errors.txt @@ -0,0 +1,28 @@ +tests/cases/conformance/jsdoc/templateTagOnConstructorFunctions.js(21,1): error TS2322: Type 'false' is not assignable to type 'number'. + + +==== tests/cases/conformance/jsdoc/templateTagOnConstructorFunctions.js (1 errors) ==== + /** + * @template {T} + * @typedef {(t: T) => T} Id + * @param {T} t + */ + function Zet(t) { + /** @type {T} */ + this.u + this.t = t + } + /** + * @param {T} v + * @param {Id} id + */ + Zet.prototype.add = function(v, id) { + this.u = v || this.t + return id(this.u) + } + var z = new Zet(1) + z.t = 2 + z.u = false + ~~~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols b/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols new file mode 100644 index 00000000000..8cf2ee99e57 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/jsdoc/templateTagOnConstructorFunctions.js === +/** + * @template {T} + * @typedef {(t: T) => T} Id + * @param {T} t + */ +function Zet(t) { +>Zet : Symbol(Zet, Decl(templateTagOnConstructorFunctions.js, 0, 0)) +>t : Symbol(t, Decl(templateTagOnConstructorFunctions.js, 5, 13)) + + /** @type {T} */ + this.u + this.t = t +>t : Symbol(Zet.t, Decl(templateTagOnConstructorFunctions.js, 7, 10)) +>t : Symbol(t, Decl(templateTagOnConstructorFunctions.js, 5, 13)) +} +/** + * @param {T} v + * @param {Id} id + */ +Zet.prototype.add = function(v, id) { +>Zet.prototype : Symbol(Zet.add, Decl(templateTagOnConstructorFunctions.js, 9, 1)) +>Zet : Symbol(Zet, Decl(templateTagOnConstructorFunctions.js, 0, 0)) +>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --)) +>add : Symbol(Zet.add, Decl(templateTagOnConstructorFunctions.js, 9, 1)) +>v : Symbol(v, Decl(templateTagOnConstructorFunctions.js, 14, 29)) +>id : Symbol(id, Decl(templateTagOnConstructorFunctions.js, 14, 31)) + + this.u = v || this.t +>this.u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 5, 17), Decl(templateTagOnConstructorFunctions.js, 14, 37)) +>this : Symbol(Zet, Decl(templateTagOnConstructorFunctions.js, 0, 0)) +>u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 5, 17), Decl(templateTagOnConstructorFunctions.js, 14, 37)) +>v : Symbol(v, Decl(templateTagOnConstructorFunctions.js, 14, 29)) +>this.t : Symbol(Zet.t, Decl(templateTagOnConstructorFunctions.js, 7, 10)) +>this : Symbol(Zet, Decl(templateTagOnConstructorFunctions.js, 0, 0)) +>t : Symbol(Zet.t, Decl(templateTagOnConstructorFunctions.js, 7, 10)) + + return id(this.u) +>id : Symbol(id, Decl(templateTagOnConstructorFunctions.js, 14, 31)) +>this.u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 5, 17), Decl(templateTagOnConstructorFunctions.js, 14, 37)) +>this : Symbol(Zet, Decl(templateTagOnConstructorFunctions.js, 0, 0)) +>u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 5, 17), Decl(templateTagOnConstructorFunctions.js, 14, 37)) +} +var z = new Zet(1) +>z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 18, 3)) +>Zet : Symbol(Zet, Decl(templateTagOnConstructorFunctions.js, 0, 0)) + +z.t = 2 +>z.t : Symbol(Zet.t, Decl(templateTagOnConstructorFunctions.js, 7, 10)) +>z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 18, 3)) +>t : Symbol(Zet.t, Decl(templateTagOnConstructorFunctions.js, 7, 10)) + +z.u = false +>z.u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 5, 17), Decl(templateTagOnConstructorFunctions.js, 14, 37)) +>z : Symbol(z, Decl(templateTagOnConstructorFunctions.js, 18, 3)) +>u : Symbol(Zet.u, Decl(templateTagOnConstructorFunctions.js, 5, 17), Decl(templateTagOnConstructorFunctions.js, 14, 37)) + diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction.types b/tests/baselines/reference/jsdocTemplateConstructorFunction.types new file mode 100644 index 00000000000..f838534aa33 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction.types @@ -0,0 +1,76 @@ +=== tests/cases/conformance/jsdoc/templateTagOnConstructorFunctions.js === +/** + * @template {T} + * @typedef {(t: T) => T} Id + * @param {T} t + */ +function Zet(t) { +>Zet : typeof Zet +>t : T + + /** @type {T} */ + this.u +>this.u : any +>this : any +>u : any + + this.t = t +>this.t = t : T +>this.t : any +>this : any +>t : any +>t : T +} +/** + * @param {T} v + * @param {Id} id + */ +Zet.prototype.add = function(v, id) { +>Zet.prototype.add = function(v, id) { this.u = v || this.t return id(this.u)} : (v: T, id: (t: T) => T) => T +>Zet.prototype.add : any +>Zet.prototype : any +>Zet : typeof Zet +>prototype : any +>add : any +>function(v, id) { this.u = v || this.t return id(this.u)} : (v: T, id: (t: T) => T) => T +>v : T +>id : (t: T) => T + + this.u = v || this.t +>this.u = v || this.t : T +>this.u : T +>this : Zet +>u : T +>v || this.t : T +>v : T +>this.t : T +>this : Zet +>t : T + + return id(this.u) +>id(this.u) : T +>id : (t: T) => T +>this.u : T +>this : Zet +>u : T +} +var z = new Zet(1) +>z : typeof Zet +>new Zet(1) : typeof Zet +>Zet : typeof Zet +>1 : 1 + +z.t = 2 +>z.t = 2 : 2 +>z.t : number +>z : typeof Zet +>t : number +>2 : 2 + +z.u = false +>z.u = false : false +>z.u : number +>z : typeof Zet +>u : number +>false : false + diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateClass.ts b/tests/cases/conformance/jsdoc/jsdocTemplateClass.ts new file mode 100644 index 00000000000..5cd0cde89be --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTemplateClass.ts @@ -0,0 +1,29 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: templateTagOnClasses.js + +/** + * @template {T} + * @typedef {(t: T) => T} Id + */ +class Foo { + /** @typedef {(t: T) => T} Id2 */ + /** @param {T} x */ + constructor (x) { + this.a = x + } + /** + * + * @param {T} x + * @param {Id} y + * @param {Id2} alpha + * @return {T} + */ + foo(x, y, alpha) { + return alpha(y(x)) + } +} +var f = new Foo(1) +var g = new Foo(false) +f.a = g.a diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction.ts b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction.ts new file mode 100644 index 00000000000..dc44afe040a --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction.ts @@ -0,0 +1,26 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: templateTagOnConstructorFunctions.js + +/** + * @template {T} + * @typedef {(t: T) => T} Id + * @param {T} t + */ +function Zet(t) { + /** @type {T} */ + this.u + this.t = t +} +/** + * @param {T} v + * @param {Id} id + */ +Zet.prototype.add = function(v, id) { + this.u = v || this.t + return id(this.u) +} +var z = new Zet(1) +z.t = 2 +z.u = false diff --git a/tests/cases/fourslash/findAllRefsJsDocTemplateTag_class_js.ts b/tests/cases/fourslash/findAllRefsJsDocTemplateTag_class_js.ts index 6577cfce15d..8ec2e86fadb 100644 --- a/tests/cases/fourslash/findAllRefsJsDocTemplateTag_class_js.ts +++ b/tests/cases/fourslash/findAllRefsJsDocTemplateTag_class_js.ts @@ -3,15 +3,14 @@ // @allowJs: true // @Filename: /a.js -// TODO: https://github.com/Microsoft/TypeScript/issues/16411 // Both uses of T should be referenced. /////** @template [|{| "isWriteAccess": true, "isDefinition": true |}T|] */ ////class C { //// constructor() { -//// /** @type {T} */ +//// /** @type {[|T|]} */ //// this.x = null; //// } ////} -verify.singleReferenceGroup("(type parameter) T in C"); +verify.singleReferenceGroup("(type parameter) T in C", test.ranges()); From 8740045d8e810930867289edbad76aef03c43671 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 20 Apr 2018 04:10:18 +0000 Subject: [PATCH 136/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index d3663b384db..ca47b5dac95 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2397,15 +2397,6 @@ - - - - - - - - - @@ -3780,20 +3771,20 @@ - + - + - + - + - + - + From 8d6c2bc1b1e902d452b02f167c611bbde9b30cb7 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 19 Apr 2018 21:53:01 -0700 Subject: [PATCH 137/229] Used return value from clearScreenIfNotWatchingForFiles --- src/compiler/watch.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 3140d975a3d..0dfe3968826 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -34,14 +34,20 @@ namespace ts { Diagnostics.Found_0_errors.code ]; - function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions) { + /** + * @returns Whether the screen was cleared. + */ + function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions): boolean { if (system.clearScreen && !options.preserveWatchOutput && !options.extendedDiagnostics && !options.diagnostics && !contains(nonClearingMessageCodes, diagnostic.code)) { system.clearScreen(); + return true; } + + return false; } /** @internal */ @@ -50,12 +56,6 @@ namespace ts { Diagnostics.File_change_detected_Starting_incremental_compilation.code, ]; - function getPlainDiagnosticPrecedingNewLines(diagnostic: Diagnostic, newLine: string, preserveWatchOutput?: boolean): string { - return !preserveWatchOutput && contains(screenStartingMessageCodes, diagnostic.code) - ? "" - : newLine; - } - function getPlainDiagnosticFollowingNewLines(diagnostic: Diagnostic, newLine: string): string { return contains(screenStartingMessageCodes, diagnostic.code) ? newLine + newLine @@ -74,8 +74,10 @@ namespace ts { system.write(output); } : (diagnostic, newLine, options) => { - clearScreenIfNotWatchingForFileChanges(system, diagnostic, options); - let output = `${getPlainDiagnosticPrecedingNewLines(diagnostic, newLine, options.preserveWatchOutput)}${new Date().toLocaleTimeString()} - `; + if (!clearScreenIfNotWatchingForFileChanges(system, diagnostic, options)) { + system.write(newLine); + } + let output = `${new Date().toLocaleTimeString()} - `; output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${getPlainDiagnosticFollowingNewLines(diagnostic, newLine)}`; system.write(output); }; From 351251193ddca4f03ed5676c2dde862734cc5aee Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 19 Apr 2018 21:54:08 -0700 Subject: [PATCH 138/229] Simplified to one output line --- src/compiler/watch.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 0dfe3968826..1b79e71efb8 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -74,11 +74,15 @@ namespace ts { system.write(output); } : (diagnostic, newLine, options) => { + let output = ""; + if (!clearScreenIfNotWatchingForFileChanges(system, diagnostic, options)) { - system.write(newLine); + output += newLine; } - let output = `${new Date().toLocaleTimeString()} - `; + + output += `${new Date().toLocaleTimeString()} - `; output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${getPlainDiagnosticFollowingNewLines(diagnostic, newLine)}`; + system.write(output); }; } From 7812e5180f2ba5facd2bb4e0232fb34e4d30dab0 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Thu, 19 Apr 2018 22:01:08 -0700 Subject: [PATCH 139/229] Trailing whitespace, oh no! --- src/compiler/watch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 1b79e71efb8..2f240300aba 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -35,7 +35,7 @@ namespace ts { ]; /** - * @returns Whether the screen was cleared. + * @returns Whether the screen was cleared. */ function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions): boolean { if (system.clearScreen && From ee834a270ab0489653e9c5339257235fb5f31e67 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 20 Apr 2018 10:10:36 +0000 Subject: [PATCH 140/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- 2 files changed, 28 insertions(+), 64 deletions(-) diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 43d2f167e96..07300f3ab7c 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -903,6 +903,12 @@ + + + + + + @@ -999,24 +1005,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2388,15 +2379,6 @@ - - - - - - - - - @@ -3771,20 +3753,20 @@ - + - + - + - + - + - + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 0e70ff04cca..d4801255fdb 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -903,6 +903,12 @@ + + + + + + @@ -999,24 +1005,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2388,15 +2379,6 @@ - - - - - - - - - @@ -3771,20 +3753,20 @@ - + - + - + - + - + - + From 4827728b168eb46745b28a0932211aa0b704de58 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Fri, 20 Apr 2018 16:26:53 +0200 Subject: [PATCH 141/229] binder: don't inline generator function's control flow Fixes: #23565 --- src/compiler/binder.ts | 5 +- .../reference/controlFlowIIFE.errors.txt | 89 +++++++++++++++ tests/baselines/reference/controlFlowIIFE.js | 103 +++++++++++++++++- .../reference/controlFlowIIFE.symbols | 48 ++++++++ .../baselines/reference/controlFlowIIFE.types | 70 ++++++++++++ .../controlFlow/controlFlowIIFE.ts | 29 ++++- 6 files changed, 340 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/controlFlowIIFE.errors.txt diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index e6e3364840d..fe77e9b4df4 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -516,8 +516,9 @@ namespace ts { const saveReturnTarget = currentReturnTarget; const saveActiveLabels = activeLabels; const saveHasExplicitReturn = hasExplicitReturn; - const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node); - // A non-async IIFE is considered part of the containing control flow. Return statements behave + const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && + !(node).asteriskToken && !!getImmediatelyInvokedFunctionExpression(node); + // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave // similarly to break statements that exit to a label just past the statement body. if (!isIIFE) { currentFlow = { flags: FlowFlags.Start }; diff --git a/tests/baselines/reference/controlFlowIIFE.errors.txt b/tests/baselines/reference/controlFlowIIFE.errors.txt new file mode 100644 index 00000000000..f8e82aff966 --- /dev/null +++ b/tests/baselines/reference/controlFlowIIFE.errors.txt @@ -0,0 +1,89 @@ +error TS2318: Cannot find global type 'IterableIterator'. +error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/controlFlow/controlFlowIIFE.ts(64,5): error TS2454: Variable 'v' is used before being assigned. +tests/cases/conformance/controlFlow/controlFlowIIFE.ts(69,6): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/controlFlow/controlFlowIIFE.ts(72,5): error TS2454: Variable 'v' is used before being assigned. + + +!!! error TS2318: Cannot find global type 'IterableIterator'. +!!! error TS2468: Cannot find global value 'Promise'. +==== tests/cases/conformance/controlFlow/controlFlowIIFE.ts (3 errors) ==== + declare function getStringOrNumber(): string | number; + + function f1() { + let x = getStringOrNumber(); + if (typeof x === "string") { + let n = function() { + return x.length; + }(); + } + } + + function f2() { + let x = getStringOrNumber(); + if (typeof x === "string") { + let n = (function() { + return x.length; + })(); + } + } + + function f3() { + let x = getStringOrNumber(); + let y: number; + if (typeof x === "string") { + let n = (z => x.length + y + z)(y = 1); + } + } + + // Repros from #8381 + + let maybeNumber: number | undefined; + (function () { + maybeNumber = 1; + })(); + maybeNumber++; + if (maybeNumber !== undefined) { + maybeNumber++; + } + + let test: string | undefined; + if (!test) { + throw new Error('Test is not defined'); + } + (() => { + test.slice(1); // No error + })(); + + // Repro from #23565 + + function f4() { + let v: number; + (function() { + v = 1; + })(); + v; + } + + function f5() { + let v: number; + (function*() { + yield 1; + v = 1; + })(); + v; // still undefined + ~ +!!! error TS2454: Variable 'v' is used before being assigned. + } + + function f6() { + let v: number; + (async function() { + ~~~~~ +!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. + v = await 1; + })(); + v; // still undefined + ~ +!!! error TS2454: Variable 'v' is used before being assigned. + } \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowIIFE.js b/tests/baselines/reference/controlFlowIIFE.js index 20bde01cba6..dfe536bcd2a 100644 --- a/tests/baselines/reference/controlFlowIIFE.js +++ b/tests/baselines/reference/controlFlowIIFE.js @@ -44,9 +44,71 @@ if (!test) { } (() => { test.slice(1); // No error -})(); +})(); + +// Repro from #23565 + +function f4() { + let v: number; + (function() { + v = 1; + })(); + v; +} + +function f5() { + let v: number; + (function*() { + yield 1; + v = 1; + })(); + v; // still undefined +} + +function f6() { + let v: number; + (async function() { + v = await 1; + })(); + v; // still undefined +} //// [controlFlowIIFE.js] +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __generator = (this && this.__generator) || function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +}; function f1() { var x = getStringOrNumber(); if (typeof x === "string") { @@ -86,3 +148,42 @@ if (!test) { (function () { test.slice(1); // No error })(); +// Repro from #23565 +function f4() { + var v; + (function () { + v = 1; + })(); + v; +} +function f5() { + var v; + (function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, 1]; + case 1: + _a.sent(); + v = 1; + return [2 /*return*/]; + } + }); + })(); + v; // still undefined +} +function f6() { + var v; + (function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, 1]; + case 1: + v = _a.sent(); + return [2 /*return*/]; + } + }); + }); + })(); + v; // still undefined +} diff --git a/tests/baselines/reference/controlFlowIIFE.symbols b/tests/baselines/reference/controlFlowIIFE.symbols index 4df906e0684..619d945cca3 100644 --- a/tests/baselines/reference/controlFlowIIFE.symbols +++ b/tests/baselines/reference/controlFlowIIFE.symbols @@ -108,3 +108,51 @@ if (!test) { >slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) })(); + +// Repro from #23565 + +function f4() { +>f4 : Symbol(f4, Decl(controlFlowIIFE.ts, 45, 5)) + + let v: number; +>v : Symbol(v, Decl(controlFlowIIFE.ts, 50, 7)) + + (function() { + v = 1; +>v : Symbol(v, Decl(controlFlowIIFE.ts, 50, 7)) + + })(); + v; +>v : Symbol(v, Decl(controlFlowIIFE.ts, 50, 7)) +} + +function f5() { +>f5 : Symbol(f5, Decl(controlFlowIIFE.ts, 55, 1)) + + let v: number; +>v : Symbol(v, Decl(controlFlowIIFE.ts, 58, 7)) + + (function*() { + yield 1; + v = 1; +>v : Symbol(v, Decl(controlFlowIIFE.ts, 58, 7)) + + })(); + v; // still undefined +>v : Symbol(v, Decl(controlFlowIIFE.ts, 58, 7)) +} + +function f6() { +>f6 : Symbol(f6, Decl(controlFlowIIFE.ts, 64, 1)) + + let v: number; +>v : Symbol(v, Decl(controlFlowIIFE.ts, 67, 7)) + + (async function() { + v = await 1; +>v : Symbol(v, Decl(controlFlowIIFE.ts, 67, 7)) + + })(); + v; // still undefined +>v : Symbol(v, Decl(controlFlowIIFE.ts, 67, 7)) +} diff --git a/tests/baselines/reference/controlFlowIIFE.types b/tests/baselines/reference/controlFlowIIFE.types index 1132649ae09..9fde9b4f99f 100644 --- a/tests/baselines/reference/controlFlowIIFE.types +++ b/tests/baselines/reference/controlFlowIIFE.types @@ -150,3 +150,73 @@ if (!test) { >1 : 1 })(); + +// Repro from #23565 + +function f4() { +>f4 : () => void + + let v: number; +>v : number + + (function() { +>(function() { v = 1; })() : void +>(function() { v = 1; }) : () => void +>function() { v = 1; } : () => void + + v = 1; +>v = 1 : 1 +>v : number +>1 : 1 + + })(); + v; +>v : number +} + +function f5() { +>f5 : () => void + + let v: number; +>v : number + + (function*() { +>(function*() { yield 1; v = 1; })() : {} +>(function*() { yield 1; v = 1; }) : () => {} +>function*() { yield 1; v = 1; } : () => {} + + yield 1; +>yield 1 : any +>1 : 1 + + v = 1; +>v = 1 : 1 +>v : number +>1 : 1 + + })(); + v; // still undefined +>v : number +} + +function f6() { +>f6 : () => void + + let v: number; +>v : number + + (async function() { +>(async function() { v = await 1; })() : Promise +>(async function() { v = await 1; }) : () => Promise +>async function() { v = await 1; } : () => Promise + + v = await 1; +>v = await 1 : 1 +>v : number +>await 1 : 1 +>1 : 1 + + })(); + v; // still undefined +>v : number +} diff --git a/tests/cases/conformance/controlFlow/controlFlowIIFE.ts b/tests/cases/conformance/controlFlow/controlFlowIIFE.ts index c72f038c1ec..a3ee39d623e 100644 --- a/tests/cases/conformance/controlFlow/controlFlowIIFE.ts +++ b/tests/cases/conformance/controlFlow/controlFlowIIFE.ts @@ -45,4 +45,31 @@ if (!test) { } (() => { test.slice(1); // No error -})(); \ No newline at end of file +})(); + +// Repro from #23565 + +function f4() { + let v: number; + (function() { + v = 1; + })(); + v; +} + +function f5() { + let v: number; + (function*() { + yield 1; + v = 1; + })(); + v; // still undefined +} + +function f6() { + let v: number; + (async function() { + v = await 1; + })(); + v; // still undefined +} \ No newline at end of file From 8e565fb4a6334d0e07c1d9041d144cbc2cc9a26e Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Fri, 20 Apr 2018 16:39:37 +0200 Subject: [PATCH 142/229] avoid generated helpers in baseline --- .../reference/controlFlowIIFE.errors.txt | 9 +- tests/baselines/reference/controlFlowIIFE.js | 87 ++++--------------- .../reference/controlFlowIIFE.symbols | 18 ++-- .../baselines/reference/controlFlowIIFE.types | 6 +- .../controlFlow/controlFlowIIFE.ts | 1 + 5 files changed, 32 insertions(+), 89 deletions(-) diff --git a/tests/baselines/reference/controlFlowIIFE.errors.txt b/tests/baselines/reference/controlFlowIIFE.errors.txt index f8e82aff966..50053a90f2c 100644 --- a/tests/baselines/reference/controlFlowIIFE.errors.txt +++ b/tests/baselines/reference/controlFlowIIFE.errors.txt @@ -1,13 +1,8 @@ -error TS2318: Cannot find global type 'IterableIterator'. -error TS2468: Cannot find global value 'Promise'. tests/cases/conformance/controlFlow/controlFlowIIFE.ts(64,5): error TS2454: Variable 'v' is used before being assigned. -tests/cases/conformance/controlFlow/controlFlowIIFE.ts(69,6): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. tests/cases/conformance/controlFlow/controlFlowIIFE.ts(72,5): error TS2454: Variable 'v' is used before being assigned. -!!! error TS2318: Cannot find global type 'IterableIterator'. -!!! error TS2468: Cannot find global value 'Promise'. -==== tests/cases/conformance/controlFlow/controlFlowIIFE.ts (3 errors) ==== +==== tests/cases/conformance/controlFlow/controlFlowIIFE.ts (2 errors) ==== declare function getStringOrNumber(): string | number; function f1() { @@ -79,8 +74,6 @@ tests/cases/conformance/controlFlow/controlFlowIIFE.ts(72,5): error TS2454: Vari function f6() { let v: number; (async function() { - ~~~~~ -!!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. v = await 1; })(); v; // still undefined diff --git a/tests/baselines/reference/controlFlowIIFE.js b/tests/baselines/reference/controlFlowIIFE.js index dfe536bcd2a..5c7fcb4bd52 100644 --- a/tests/baselines/reference/controlFlowIIFE.js +++ b/tests/baselines/reference/controlFlowIIFE.js @@ -74,66 +74,31 @@ function f6() { } //// [controlFlowIIFE.js] -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [0, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; function f1() { - var x = getStringOrNumber(); + let x = getStringOrNumber(); if (typeof x === "string") { - var n = function () { + let n = function () { return x.length; }(); } } function f2() { - var x = getStringOrNumber(); + let x = getStringOrNumber(); if (typeof x === "string") { - var n = (function () { + let n = (function () { return x.length; })(); } } function f3() { - var x = getStringOrNumber(); - var y; + let x = getStringOrNumber(); + let y; if (typeof x === "string") { - var n = (function (z) { return x.length + y + z; })(y = 1); + let n = (z => x.length + y + z)(y = 1); } } // Repros from #8381 -var maybeNumber; +let maybeNumber; (function () { maybeNumber = 1; })(); @@ -141,49 +106,33 @@ maybeNumber++; if (maybeNumber !== undefined) { maybeNumber++; } -var test; +let test; if (!test) { throw new Error('Test is not defined'); } -(function () { +(() => { test.slice(1); // No error })(); // Repro from #23565 function f4() { - var v; + let v; (function () { v = 1; })(); v; } function f5() { - var v; - (function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, 1]; - case 1: - _a.sent(); - v = 1; - return [2 /*return*/]; - } - }); + let v; + (function* () { + yield 1; + v = 1; })(); v; // still undefined } function f6() { - var v; - (function () { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, 1]; - case 1: - v = _a.sent(); - return [2 /*return*/]; - } - }); - }); + let v; + (async function () { + v = await 1; })(); v; // still undefined } diff --git a/tests/baselines/reference/controlFlowIIFE.symbols b/tests/baselines/reference/controlFlowIIFE.symbols index 619d945cca3..038d398c649 100644 --- a/tests/baselines/reference/controlFlowIIFE.symbols +++ b/tests/baselines/reference/controlFlowIIFE.symbols @@ -16,9 +16,9 @@ function f1() { >n : Symbol(n, Decl(controlFlowIIFE.ts, 5, 11)) return x.length; ->x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) >x : Symbol(x, Decl(controlFlowIIFE.ts, 3, 7)) ->length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) }(); } @@ -38,9 +38,9 @@ function f2() { >n : Symbol(n, Decl(controlFlowIIFE.ts, 14, 11)) return x.length; ->x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) >x : Symbol(x, Decl(controlFlowIIFE.ts, 12, 7)) ->length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) })(); } @@ -62,9 +62,9 @@ function f3() { let n = (z => x.length + y + z)(y = 1); >n : Symbol(n, Decl(controlFlowIIFE.ts, 24, 11)) >z : Symbol(z, Decl(controlFlowIIFE.ts, 24, 17)) ->x.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) >x : Symbol(x, Decl(controlFlowIIFE.ts, 21, 7)) ->length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) >y : Symbol(y, Decl(controlFlowIIFE.ts, 22, 7)) >z : Symbol(z, Decl(controlFlowIIFE.ts, 24, 17)) >y : Symbol(y, Decl(controlFlowIIFE.ts, 22, 7)) @@ -99,13 +99,13 @@ if (!test) { >test : Symbol(test, Decl(controlFlowIIFE.ts, 39, 3)) throw new Error('Test is not defined'); ->Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) } (() => { test.slice(1); // No error ->test.slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +>test.slice : Symbol(String.slice, Decl(lib.es5.d.ts, --, --)) >test : Symbol(test, Decl(controlFlowIIFE.ts, 39, 3)) ->slice : Symbol(String.slice, Decl(lib.d.ts, --, --)) +>slice : Symbol(String.slice, Decl(lib.es5.d.ts, --, --)) })(); diff --git a/tests/baselines/reference/controlFlowIIFE.types b/tests/baselines/reference/controlFlowIIFE.types index 9fde9b4f99f..7aaaad159fc 100644 --- a/tests/baselines/reference/controlFlowIIFE.types +++ b/tests/baselines/reference/controlFlowIIFE.types @@ -181,9 +181,9 @@ function f5() { >v : number (function*() { ->(function*() { yield 1; v = 1; })() : {} ->(function*() { yield 1; v = 1; }) : () => {} ->function*() { yield 1; v = 1; } : () => {} +>(function*() { yield 1; v = 1; })() : IterableIterator +>(function*() { yield 1; v = 1; }) : () => IterableIterator +>function*() { yield 1; v = 1; } : () => IterableIterator yield 1; >yield 1 : any diff --git a/tests/cases/conformance/controlFlow/controlFlowIIFE.ts b/tests/cases/conformance/controlFlow/controlFlowIIFE.ts index a3ee39d623e..8cd9047cb05 100644 --- a/tests/cases/conformance/controlFlow/controlFlowIIFE.ts +++ b/tests/cases/conformance/controlFlow/controlFlowIIFE.ts @@ -1,4 +1,5 @@ // @strictNullChecks: true +// @target: ES2017 declare function getStringOrNumber(): string | number; From f57ba59a77cde7f7eb7d92761e53ff267f4ea325 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Fri, 20 Apr 2018 17:42:29 +0200 Subject: [PATCH 143/229] resolveEntityName: don't return false (#23563) Fixes: #23562 --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bfc9c1fd550..c1cb7166015 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2061,7 +2061,7 @@ namespace ts { let symbol: Symbol; if (name.kind === SyntaxKind.Identifier) { const message = meaning === namespaceMeaning ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0; - const symbolFromJSPrototype = isInJavaScriptFile(name) && resolveEntityNameFromJSPrototype(name, meaning); + const symbolFromJSPrototype = isInJavaScriptFile(name) ? resolveEntityNameFromJSPrototype(name, meaning) : undefined; symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true); if (!symbol) { return symbolFromJSPrototype; From 760f8b85ab61bd1b0c4981203c702e2c2b0055f5 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 20 Apr 2018 16:10:25 +0000 Subject: [PATCH 144/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- 2 files changed, 28 insertions(+), 64 deletions(-) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 0ef1aeed0cc..3715eb460a0 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -912,6 +912,12 @@ + + + + + + @@ -1008,24 +1014,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2397,15 +2388,6 @@ - - - - - - - - - @@ -3780,20 +3762,20 @@ - + - + - + - + - + - + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 36e67c41077..94427fcd4ca 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -893,6 +893,12 @@ + + + + + + @@ -989,24 +995,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2378,15 +2369,6 @@ - - - - - - - - - @@ -3761,20 +3743,20 @@ - + - + - + - + - + - + From 94cc59ca60f9f813a91a33907627d8504cb83b70 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 20 Apr 2018 09:43:20 -0700 Subject: [PATCH 145/229] Support getting JSDoc comment starting at a FunctionType node (#23546) * Support getting JSDoc comment starting at a FunctionType node * Move || to end of line --- src/compiler/utilities.ts | 16 ++++++++-------- tests/cases/fourslash/commentsVariables.ts | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 730c3fc51d4..e4afb3339d0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1818,10 +1818,8 @@ namespace ts { function getJSDocCommentsAndTagsWorker(node: Node): void { const parent = node.parent; - if (parent && - (parent.kind === SyntaxKind.PropertyAssignment || - parent.kind === SyntaxKind.PropertyDeclaration || - getNestedModuleDeclaration(parent))) { + if (!parent) return; + if (parent.kind === SyntaxKind.PropertyAssignment || parent.kind === SyntaxKind.PropertyDeclaration || getNestedModuleDeclaration(parent)) { getJSDocCommentsAndTagsWorker(parent); } // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. @@ -1830,16 +1828,18 @@ namespace ts { // * @returns {number} // */ // var x = function(name) { return name.length; } - if (parent && parent.parent && + if (parent.parent && (getSingleVariableOfVariableStatement(parent.parent) === node || getSourceOfAssignment(parent.parent))) { getJSDocCommentsAndTagsWorker(parent.parent); } - if (parent && parent.parent && parent.parent.parent && - (getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node || getSourceOfDefaultedAssignment(parent.parent.parent))) { + if (parent.parent && parent.parent.parent && + (getSingleVariableOfVariableStatement(parent.parent.parent) || + getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node || + getSourceOfDefaultedAssignment(parent.parent.parent))) { getJSDocCommentsAndTagsWorker(parent.parent.parent); } if (isBinaryExpression(node) && getSpecialPropertyAssignmentKind(node) !== SpecialPropertyAssignmentKind.None || - parent && isBinaryExpression(parent) && getSpecialPropertyAssignmentKind(parent) !== SpecialPropertyAssignmentKind.None || + isBinaryExpression(parent) && getSpecialPropertyAssignmentKind(parent) !== SpecialPropertyAssignmentKind.None || node.kind === SyntaxKind.PropertyAccessExpression && node.parent && node.parent.kind === SyntaxKind.ExpressionStatement) { getJSDocCommentsAndTagsWorker(parent); } diff --git a/tests/cases/fourslash/commentsVariables.ts b/tests/cases/fourslash/commentsVariables.ts index 4d5682ef401..bf7e13ee51c 100644 --- a/tests/cases/fourslash/commentsVariables.ts +++ b/tests/cases/fourslash/commentsVariables.ts @@ -59,8 +59,8 @@ verify.currentSignatureHelpDocCommentIs("foos comment"); verify.quickInfoAt("5q", "function foo(): void", "foos comment"); goTo.marker('6'); -verify.currentSignatureHelpDocCommentIs(""); -verify.quickInfoAt("6q", "var fooVar: () => void"); +verify.currentSignatureHelpDocCommentIs("fooVar comment"); +verify.quickInfoAt("6q", "var fooVar: () => void", "fooVar comment"); goTo.marker('7'); verify.completionListContains("foo", "function foo(): void", "foos comment"); @@ -71,9 +71,9 @@ verify.currentSignatureHelpDocCommentIs("foos comment"); verify.quickInfoAt("8q", "function foo(): void", "foos comment"); goTo.marker('9'); -verify.currentSignatureHelpDocCommentIs(""); +verify.currentSignatureHelpDocCommentIs("fooVar comment"); verify.quickInfos({ - "9q": "var fooVar: () => void", + "9q": ["var fooVar: () => void", "fooVar comment"], "9aq": ["var fooVar: () => void", "fooVar comment"] }); From 18c3f5ffa07700f8e4788f0c9815e0c29f424067 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 20 Apr 2018 09:43:38 -0700 Subject: [PATCH 146/229] Use getFirstConstructorWithBody in one more place, and simplify other class members iteration (#23567) --- src/compiler/utilities.ts | 6 +----- .../codefixes/fixStrictClassInitialization.ts | 2 +- src/services/findAllReferences.ts | 14 +++++--------- src/services/jsDoc.ts | 11 ++++------- 4 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e4afb3339d0..9897d68603e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2933,11 +2933,7 @@ namespace ts { } export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration { - return forEach(node.members, member => { - if (member.kind === SyntaxKind.Constructor && nodeIsPresent((member).body)) { - return member; - } - }); + return find(node.members, (member): member is ConstructorDeclaration => isConstructorDeclaration(member) && nodeIsPresent(member.body)); } function getSetAccessorValueParameter(accessor: SetAccessorDeclaration): ParameterDeclaration | undefined { diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts index 8d4e457662f..6c211b86f8d 100644 --- a/src/services/codefixes/fixStrictClassInitialization.ts +++ b/src/services/codefixes/fixStrictClassInitialization.ts @@ -127,7 +127,7 @@ namespace ts.codefix { const classDeclaration = getClassLikeDeclarationOfSymbol(type.symbol); if (!classDeclaration || hasModifier(classDeclaration, ModifierFlags.Abstract)) return undefined; - const constructorDeclaration = find(classDeclaration.members, (m): m is ConstructorDeclaration => isConstructorDeclaration(m) && !!m.body)!; + const constructorDeclaration = getFirstConstructorWithBody(classDeclaration); if (constructorDeclaration && constructorDeclaration.parameters.length) return undefined; return createNew(createIdentifier(type.symbol.name), /*typeArguments*/ undefined, /*argumentsArray*/ undefined); diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 57fe2a7a0e4..1b4e81928c0 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1014,21 +1014,17 @@ namespace ts.FindAllReferences.Core { function addClassStaticThisReferences(referenceLocation: Node, search: Search, state: State): void { addReference(referenceLocation, search.symbol, state); - if (!state.options.isForRename && isClassLike(referenceLocation.parent)) { - Debug.assert(referenceLocation.parent.name === referenceLocation); - // This is the class declaration. - addStaticThisReferences(referenceLocation.parent, state.referenceAdder(search.symbol)); - } - } - - function addStaticThisReferences(classLike: ClassLikeDeclaration, pusher: (node: Node) => void): void { + const classLike = referenceLocation.parent; + if (state.options.isForRename || !isClassLike(classLike)) return; + Debug.assert(classLike.name === referenceLocation); + const addRef = state.referenceAdder(search.symbol); for (const member of classLike.members) { if (!(isMethodOrAccessor(member) && hasModifier(member, ModifierFlags.Static))) { continue; } member.body.forEachChild(function cb(node) { if (node.kind === SyntaxKind.ThisKeyword) { - pusher(node); + addRef(node); } else if (!isFunctionLike(node)) { node.forEachChild(cb); diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index d0860c3e161..ca0dafbc74c 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -365,13 +365,10 @@ namespace ts.JsDoc { case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: return (rightHandSide).parameters; - case SyntaxKind.ClassExpression: - for (const member of (rightHandSide).members) { - if (member.kind === SyntaxKind.Constructor) { - return (member).parameters; - } - } - break; + case SyntaxKind.ClassExpression: { + const ctr = find((rightHandSide as ClassExpression).members, isConstructorDeclaration); + return ctr && ctr.parameters; + } } return emptyArray; From eb7bbfb28ed93a212b24f71be3a837fb4c58ffd4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Apr 2018 09:55:59 -0700 Subject: [PATCH 147/229] Properties with numeric names have numeric literal types in keyof T --- src/compiler/checker.ts | 83 +++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 48 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 62b4f537ec6..af069d548a7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8206,12 +8206,15 @@ namespace ts { function getLiteralTypeFromPropertyName(prop: Symbol, include: TypeFlags) { if (!(getDeclarationModifierFlagsFromSymbol(prop) & ModifierFlags.NonPublicAccessibilityModifier)) { - const nameType = getLateBoundSymbol(prop).nameType; - if (nameType) { - return nameType.flags & include ? nameType : neverType; + let type = getLateBoundSymbol(prop).nameType; + if (!type && !isKnownSymbol(prop)) { + const name = getNameOfDeclaration(prop.valueDeclaration); + type = name && isNumericLiteral(name) ? getLiteralType(+name.text) : + name && name.kind === SyntaxKind.ComputedPropertyName && isNumericLiteral(name.expression) ? getLiteralType(+name.expression.text) : + getLiteralType(symbolName(prop)); } - if (!isKnownSymbol(prop)) { - return getLiteralType(symbolName(prop)); + if (type && type.flags & include) { + return type; } } return neverType; @@ -15369,6 +15372,7 @@ namespace ts { let patternWithComputedProperties = false; let hasComputedStringProperty = false; let hasComputedNumberProperty = false; + if (isInJSFile && node.properties.length === 0) { // an empty JS object literal that nonetheless has members is a JS namespace const symbol = getSymbolOfNode(node); @@ -15384,47 +15388,28 @@ namespace ts { for (let i = 0; i < node.properties.length; i++) { const memberDecl = node.properties[i]; let member = getSymbolOfNode(memberDecl); - let literalName: __String | undefined; + const computedNameType = memberDecl.name && memberDecl.name.kind === SyntaxKind.ComputedPropertyName && !isWellKnownSymbolSyntactically(memberDecl.name.expression) ? + checkComputedPropertyName(memberDecl.name) : undefined; if (memberDecl.kind === SyntaxKind.PropertyAssignment || memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment || isObjectLiteralMethod(memberDecl)) { - let jsdocType: Type; + let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) : + memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(memberDecl.name, checkMode) : + checkObjectLiteralMethod(memberDecl, checkMode); if (isInJSFile) { - jsdocType = getTypeForDeclarationFromJSDocComment(memberDecl); - } - - let type: Type; - if (memberDecl.kind === SyntaxKind.PropertyAssignment) { - if (memberDecl.name.kind === SyntaxKind.ComputedPropertyName) { - const t = checkComputedPropertyName(memberDecl.name); - if (t.flags & TypeFlags.Literal) { - literalName = escapeLeadingUnderscores("" + (t as LiteralType).value); - } + const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl); + if (jsDocType) { + checkTypeAssignableTo(type, jsDocType, memberDecl); + type = jsDocType; } - type = checkPropertyAssignment(memberDecl, checkMode); } - else if (memberDecl.kind === SyntaxKind.MethodDeclaration) { - type = checkObjectLiteralMethod(memberDecl, checkMode); - } - else { - Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment); - type = checkExpressionForMutableLocation(memberDecl.name, checkMode); - } - - if (jsdocType) { - checkTypeAssignableTo(type, jsdocType, memberDecl); - type = jsdocType; - } - typeFlags |= type.flags; - - const nameType = hasLateBindableName(memberDecl) ? checkComputedPropertyName(memberDecl.name) : undefined; - const hasLateBoundName = nameType && isTypeUsableAsLateBoundName(nameType); - const prop = hasLateBoundName - ? createSymbol(SymbolFlags.Property | member.flags, getLateBoundNameFromType(nameType as LiteralType | UniqueESSymbolType), CheckFlags.Late) - : createSymbol(SymbolFlags.Property | member.flags, literalName || member.escapedName); - - if (hasLateBoundName) { + const nameType = computedNameType && computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique ? + computedNameType : undefined; + const prop = nameType ? + createSymbol(SymbolFlags.Property | member.flags, getLateBoundNameFromType(nameType), CheckFlags.Late) : + createSymbol(SymbolFlags.Property | member.flags, member.escapedName); + if (nameType) { prop.nameType = nameType; } @@ -15437,9 +15422,6 @@ namespace ts { if (isOptional) { prop.flags |= SymbolFlags.Optional; } - if (!literalName && hasDynamicName(memberDecl)) { - patternWithComputedProperties = true; - } } else if (contextualTypeHasPattern && !(getObjectFlags(contextualType) & ObjectFlags.ObjectLiteralPatternWithComputedProperties)) { // If object literal is contextually typed by the implied type of a binding pattern, and if the @@ -15495,12 +15477,17 @@ namespace ts { checkNodeDeferred(memberDecl); } - if (!literalName && hasNonBindableDynamicName(memberDecl)) { - if (isNumericName(memberDecl.name)) { - hasComputedNumberProperty = true; - } - else { - hasComputedStringProperty = true; + if (computedNameType && !(computedNameType.flags & TypeFlags.StringOrNumberLiteralOrUnique)) { + if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) { + if (isTypeAssignableTo(computedNameType, numberType)) { + hasComputedNumberProperty = true; + } + else { + hasComputedStringProperty = true; + } + if (inDestructuringPattern) { + patternWithComputedProperties = true; + } } } else { From b38e42e41e16592368ea3967a2bca271dcdbef5a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Apr 2018 09:56:07 -0700 Subject: [PATCH 148/229] Accept new baselines --- tests/baselines/reference/computedPropertyNames10_ES5.types | 4 ++-- tests/baselines/reference/computedPropertyNames10_ES6.types | 4 ++-- tests/baselines/reference/computedPropertyNames28_ES5.types | 4 ++-- tests/baselines/reference/computedPropertyNames28_ES6.types | 4 ++-- tests/baselines/reference/computedPropertyNames30_ES5.types | 4 ++-- tests/baselines/reference/computedPropertyNames30_ES6.types | 4 ++-- tests/baselines/reference/computedPropertyNames5_ES5.types | 4 ++-- tests/baselines/reference/computedPropertyNames5_ES6.types | 4 ++-- tests/baselines/reference/computedPropertyNames9_ES5.types | 4 ++-- tests/baselines/reference/computedPropertyNames9_ES6.types | 4 ++-- tests/baselines/reference/parserComputedPropertyName41.types | 4 ++-- tests/baselines/reference/symbolProperty3.types | 4 ++-- 12 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/baselines/reference/computedPropertyNames10_ES5.types b/tests/baselines/reference/computedPropertyNames10_ES5.types index 717e12f7216..d12636585b6 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES5.types +++ b/tests/baselines/reference/computedPropertyNames10_ES5.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; } ->{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; } +>v : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; [`hello bye`](): void; } +>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; [`hello bye`](): void; } [s]() { }, >[s] : () => void diff --git a/tests/baselines/reference/computedPropertyNames10_ES6.types b/tests/baselines/reference/computedPropertyNames10_ES6.types index b615e9e4739..fab486ff57a 100644 --- a/tests/baselines/reference/computedPropertyNames10_ES6.types +++ b/tests/baselines/reference/computedPropertyNames10_ES6.types @@ -9,8 +9,8 @@ var a: any; >a : any var v = { ->v : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; } ->{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; } +>v : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; [`hello bye`](): void; } +>{ [s]() { }, [n]() { }, [s + s]() { }, [s + n]() { }, [+s]() { }, [""]() { }, [0]() { }, [a]() { }, [true]() { }, [`hello bye`]() { }, [`hello ${a} bye`]() { }} : { [x: string]: () => void; [x: number]: () => void; [""](): void; [0](): void; [`hello bye`](): void; } [s]() { }, >[s] : () => void diff --git a/tests/baselines/reference/computedPropertyNames28_ES5.types b/tests/baselines/reference/computedPropertyNames28_ES5.types index b440f86c986..c353b1bdb83 100644 --- a/tests/baselines/reference/computedPropertyNames28_ES5.types +++ b/tests/baselines/reference/computedPropertyNames28_ES5.types @@ -12,8 +12,8 @@ class C extends Base { >super : typeof Base var obj = { ->obj : { [x: string]: () => void; } ->{ [(super(), "prop")]() { } } : { [x: string]: () => void; } +>obj : { [(super(), "prop")](): void; } +>{ [(super(), "prop")]() { } } : { [(super(), "prop")](): void; } [(super(), "prop")]() { } >[(super(), "prop")] : () => void diff --git a/tests/baselines/reference/computedPropertyNames28_ES6.types b/tests/baselines/reference/computedPropertyNames28_ES6.types index a947b6f8a95..97d4f9d591f 100644 --- a/tests/baselines/reference/computedPropertyNames28_ES6.types +++ b/tests/baselines/reference/computedPropertyNames28_ES6.types @@ -12,8 +12,8 @@ class C extends Base { >super : typeof Base var obj = { ->obj : { [x: string]: () => void; } ->{ [(super(), "prop")]() { } } : { [x: string]: () => void; } +>obj : { [(super(), "prop")](): void; } +>{ [(super(), "prop")]() { } } : { [(super(), "prop")](): void; } [(super(), "prop")]() { } >[(super(), "prop")] : () => void diff --git a/tests/baselines/reference/computedPropertyNames30_ES5.types b/tests/baselines/reference/computedPropertyNames30_ES5.types index 1d50a1d19f3..0344bc7924a 100644 --- a/tests/baselines/reference/computedPropertyNames30_ES5.types +++ b/tests/baselines/reference/computedPropertyNames30_ES5.types @@ -15,8 +15,8 @@ class C extends Base { >() => { var obj = { // Ideally, we would capture this. But the reference is // illegal, and not capturing this is consistent with //treatment of other similar violations. [(super(), "prop")]() { } }; } : () => void var obj = { ->obj : { [x: string]: () => void; } ->{ // Ideally, we would capture this. But the reference is // illegal, and not capturing this is consistent with //treatment of other similar violations. [(super(), "prop")]() { } } : { [x: string]: () => void; } +>obj : { [(super(), "prop")](): void; } +>{ // Ideally, we would capture this. But the reference is // illegal, and not capturing this is consistent with //treatment of other similar violations. [(super(), "prop")]() { } } : { [(super(), "prop")](): void; } // Ideally, we would capture this. But the reference is // illegal, and not capturing this is consistent with diff --git a/tests/baselines/reference/computedPropertyNames30_ES6.types b/tests/baselines/reference/computedPropertyNames30_ES6.types index 3d2a39f4fe9..ef7e95f46f2 100644 --- a/tests/baselines/reference/computedPropertyNames30_ES6.types +++ b/tests/baselines/reference/computedPropertyNames30_ES6.types @@ -15,8 +15,8 @@ class C extends Base { >() => { var obj = { // Ideally, we would capture this. But the reference is // illegal, and not capturing this is consistent with //treatment of other similar violations. [(super(), "prop")]() { } }; } : () => void var obj = { ->obj : { [x: string]: () => void; } ->{ // Ideally, we would capture this. But the reference is // illegal, and not capturing this is consistent with //treatment of other similar violations. [(super(), "prop")]() { } } : { [x: string]: () => void; } +>obj : { [(super(), "prop")](): void; } +>{ // Ideally, we would capture this. But the reference is // illegal, and not capturing this is consistent with //treatment of other similar violations. [(super(), "prop")]() { } } : { [(super(), "prop")](): void; } // Ideally, we would capture this. But the reference is // illegal, and not capturing this is consistent with diff --git a/tests/baselines/reference/computedPropertyNames5_ES5.types b/tests/baselines/reference/computedPropertyNames5_ES5.types index b185ee47f4d..64b51175c33 100644 --- a/tests/baselines/reference/computedPropertyNames5_ES5.types +++ b/tests/baselines/reference/computedPropertyNames5_ES5.types @@ -3,8 +3,8 @@ var b: boolean; >b : boolean var v = { ->v : { [x: string]: number; [x: number]: any; [true]: number; } ->{ [b]: 0, [true]: 1, [[]]: 0, [{}]: 0, [undefined]: undefined, [null]: null} : { [x: string]: number; [x: number]: null; [true]: number; } +>v : { [x: number]: any; } +>{ [b]: 0, [true]: 1, [[]]: 0, [{}]: 0, [undefined]: undefined, [null]: null} : { [x: number]: null; } [b]: 0, >[b] : number diff --git a/tests/baselines/reference/computedPropertyNames5_ES6.types b/tests/baselines/reference/computedPropertyNames5_ES6.types index 62c798a8b08..5ffcba5cbc6 100644 --- a/tests/baselines/reference/computedPropertyNames5_ES6.types +++ b/tests/baselines/reference/computedPropertyNames5_ES6.types @@ -3,8 +3,8 @@ var b: boolean; >b : boolean var v = { ->v : { [x: string]: number; [x: number]: any; [true]: number; } ->{ [b]: 0, [true]: 1, [[]]: 0, [{}]: 0, [undefined]: undefined, [null]: null} : { [x: string]: number; [x: number]: null; [true]: number; } +>v : { [x: number]: any; } +>{ [b]: 0, [true]: 1, [[]]: 0, [{}]: 0, [undefined]: undefined, [null]: null} : { [x: number]: null; } [b]: 0, >[b] : number diff --git a/tests/baselines/reference/computedPropertyNames9_ES5.types b/tests/baselines/reference/computedPropertyNames9_ES5.types index dd37aca47b9..d85aefa5f1c 100644 --- a/tests/baselines/reference/computedPropertyNames9_ES5.types +++ b/tests/baselines/reference/computedPropertyNames9_ES5.types @@ -19,8 +19,8 @@ function f(x): any { } >x : any var v = { ->v : { [x: string]: number; [x: number]: number; [f(true)]: number; } ->{ [f("")]: 0, [f(0)]: 0, [f(true)]: 0} : { [x: string]: number; [x: number]: number; [f(true)]: number; } +>v : { [x: string]: number; [x: number]: number; } +>{ [f("")]: 0, [f(0)]: 0, [f(true)]: 0} : { [x: string]: number; [x: number]: number; } [f("")]: 0, >[f("")] : number diff --git a/tests/baselines/reference/computedPropertyNames9_ES6.types b/tests/baselines/reference/computedPropertyNames9_ES6.types index 02bd0eabb9a..35aac1bbea7 100644 --- a/tests/baselines/reference/computedPropertyNames9_ES6.types +++ b/tests/baselines/reference/computedPropertyNames9_ES6.types @@ -19,8 +19,8 @@ function f(x): any { } >x : any var v = { ->v : { [x: string]: number; [x: number]: number; [f(true)]: number; } ->{ [f("")]: 0, [f(0)]: 0, [f(true)]: 0} : { [x: string]: number; [x: number]: number; [f(true)]: number; } +>v : { [x: string]: number; [x: number]: number; } +>{ [f("")]: 0, [f(0)]: 0, [f(true)]: 0} : { [x: string]: number; [x: number]: number; } [f("")]: 0, >[f("")] : number diff --git a/tests/baselines/reference/parserComputedPropertyName41.types b/tests/baselines/reference/parserComputedPropertyName41.types index 897c4252f26..071ee36e18f 100644 --- a/tests/baselines/reference/parserComputedPropertyName41.types +++ b/tests/baselines/reference/parserComputedPropertyName41.types @@ -1,7 +1,7 @@ === tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName41.ts === var v = { ->v : { [x: string]: boolean; } ->{ [0 in []]: true} : { [x: string]: boolean; } +>v : {} +>{ [0 in []]: true} : {} [0 in []]: true >[0 in []] : boolean diff --git a/tests/baselines/reference/symbolProperty3.types b/tests/baselines/reference/symbolProperty3.types index df4707a207c..6975051d002 100644 --- a/tests/baselines/reference/symbolProperty3.types +++ b/tests/baselines/reference/symbolProperty3.types @@ -4,8 +4,8 @@ var s = Symbol; >Symbol : SymbolConstructor var x = { ->x : { [x: string]: number | (() => void); } ->{ [s]: 0, [s]() { }, get [s]() { return 0; }} : { [x: string]: number | (() => void); } +>x : {} +>{ [s]: 0, [s]() { }, get [s]() { return 0; }} : {} [s]: 0, >[s] : number From 22f2b118b724013e146265a34cac71638f48ade6 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 20 Apr 2018 10:25:58 -0700 Subject: [PATCH 149/229] Add 'triggerCharacter' option for completions requests (#23491) * Add 'triggerCharacter' option for completions requests * mhegazy code review * More code review * Handle '<' in comment --- src/harness/fourslash.ts | 3 ++ src/server/protocol.ts | 1 + src/server/session.ts | 1 + src/services/completions.ts | 30 +++++++++++++- src/services/services.ts | 3 +- src/services/shims.ts | 2 +- src/services/types.ts | 3 +- .../reference/api/tsserverlibrary.d.ts | 4 +- tests/baselines/reference/api/typescript.d.ts | 3 +- .../fourslash/completionsTriggerCharacter.ts | 39 +++++++++++++++++++ tests/cases/fourslash/fourslash.ts | 2 + 11 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 tests/cases/fourslash/completionsTriggerCharacter.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 75915c915ed..f65681909fa 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -842,6 +842,7 @@ namespace FourSlash { const actualCompletions = this.getCompletionListAtCaret(options); if (!actualCompletions) { + if (expected === undefined) return; this.raiseError(`No completions at position '${this.currentCaretPosition}'.`); } @@ -4653,10 +4654,12 @@ namespace FourSlashInterface { export type ExpectedCompletionEntry = string | { name: string, insertText?: string, replacementSpan?: FourSlash.Range }; export interface CompletionsAtOptions extends Partial { + triggerCharacter?: string; isNewIdentifierLocation?: boolean; } export interface VerifyCompletionListContainsOptions extends ts.UserPreferences { + triggerCharacter?: string; sourceDisplay: string; isRecommended?: true; insertText?: string; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 7a258a904c2..55ad2a6c36b 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -1749,6 +1749,7 @@ namespace ts.server.protocol { * Optional prefix to apply to possible completions. */ prefix?: string; + triggerCharacter?: string; /** * @deprecated Use UserPreferences.includeCompletionsForModuleExports */ diff --git a/src/server/session.ts b/src/server/session.ts index 27044ec369d..363369c4057 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1287,6 +1287,7 @@ namespace ts.server { const completions = project.getLanguageService().getCompletionsAtPosition(file, position, { ...this.getPreferences(file), + triggerCharacter: args.triggerCharacter, includeExternalModuleExports: args.includeExternalModuleExports, includeInsertTextCompletions: args.includeInsertTextCompletions }); diff --git a/src/services/completions.ts b/src/services/completions.ts index 3100e4a13a9..f887d28cf10 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -25,7 +25,7 @@ namespace ts.Completions { const enum GlobalsSearch { Continue, Success, Fail } - export function getCompletionsAtPosition(host: LanguageServiceHost, program: Program, log: Log, sourceFile: SourceFile, position: number, preferences: UserPreferences): CompletionInfo | undefined { + export function getCompletionsAtPosition(host: LanguageServiceHost, program: Program, log: Log, sourceFile: SourceFile, position: number, preferences: UserPreferences, triggerCharacter: string | undefined): CompletionInfo | undefined { const typeChecker = program.getTypeChecker(); const compilerOptions = program.getCompilerOptions(); if (isInReferenceComment(sourceFile, position)) { @@ -34,6 +34,7 @@ namespace ts.Completions { } const contextToken = findPrecedingToken(position, sourceFile); + if (triggerCharacter && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) return undefined; if (isInString(sourceFile, position, contextToken)) { return !contextToken || !isStringLiteralLike(contextToken) @@ -2197,4 +2198,31 @@ namespace ts.Completions { function hasIndexSignature(type: Type): boolean { return !!type.getStringIndexType() || !!type.getNumberIndexType(); } + + function isValidTrigger(sourceFile: SourceFile, triggerCharacter: string, contextToken: Node, position: number): boolean { + switch (triggerCharacter) { + case '"': + case "'": + case "`": + // Only automatically bring up completions if this is an opening quote. + return isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1; + case "<": + // Opening JSX tag + return contextToken.kind === SyntaxKind.LessThanToken && contextToken.parent.kind !== SyntaxKind.BinaryExpression; + default: + return Debug.fail(triggerCharacter); + } + } + + function isStringLiteralOrTemplate(node: Node): node is StringLiteralLike | TemplateExpression | TaggedTemplateExpression { + switch (node.kind) { + case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateExpression: + case SyntaxKind.TaggedTemplateExpression: + return true; + default: + return false; + } + } } diff --git a/src/services/services.ts b/src/services/services.ts index a192231405a..d395f1cdbc0 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1409,7 +1409,8 @@ namespace ts { log, getValidSourceFile(fileName), position, - fullPreferences); + fullPreferences, + options.triggerCharacter); } function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences = defaultPreferences): CompletionEntryDetails { diff --git a/src/services/shims.ts b/src/services/shims.ts index b8beccab20b..d0735cc1717 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -912,7 +912,7 @@ namespace ts { * to provide at the given source position and providing a member completion * list if requested. */ - public getCompletionsAtPosition(fileName: string, position: number, preferences: UserPreferences | undefined) { + public getCompletionsAtPosition(fileName: string, position: number, preferences: GetCompletionsAtPositionOptions | undefined) { return this.forwardJSONCall( `getCompletionsAtPosition('${fileName}', ${position}, ${preferences})`, () => this.languageService.getCompletionsAtPosition(fileName, position, preferences) diff --git a/src/services/types.ts b/src/services/types.ts index 01b8b5ad4d4..1c4a38b10c6 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -354,8 +354,9 @@ namespace ts { export type OrganizeImportsScope = CombinedCodeFixScope; - /** @deprecated Use UserPreferences */ export interface GetCompletionsAtPositionOptions extends UserPreferences { + /** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */ + triggerCharacter?: string; /** @deprecated Use includeCompletionsForModuleExports */ includeExternalModuleExports?: boolean; /** @deprecated Use includeCompletionsWithInsertText */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index b9cf50f14d9..0fc77ba2afa 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4455,8 +4455,9 @@ declare namespace ts { fileName: string; } type OrganizeImportsScope = CombinedCodeFixScope; - /** @deprecated Use UserPreferences */ interface GetCompletionsAtPositionOptions extends UserPreferences { + /** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */ + triggerCharacter?: string; /** @deprecated Use includeCompletionsForModuleExports */ includeExternalModuleExports?: boolean; /** @deprecated Use includeCompletionsWithInsertText */ @@ -6667,6 +6668,7 @@ declare namespace ts.server.protocol { * Optional prefix to apply to possible completions. */ prefix?: string; + triggerCharacter?: string; /** * @deprecated Use UserPreferences.includeCompletionsForModuleExports */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f5114e2397c..94ece008de1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4455,8 +4455,9 @@ declare namespace ts { fileName: string; } type OrganizeImportsScope = CombinedCodeFixScope; - /** @deprecated Use UserPreferences */ interface GetCompletionsAtPositionOptions extends UserPreferences { + /** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */ + triggerCharacter?: string; /** @deprecated Use includeCompletionsForModuleExports */ includeExternalModuleExports?: boolean; /** @deprecated Use includeCompletionsWithInsertText */ diff --git a/tests/cases/fourslash/completionsTriggerCharacter.ts b/tests/cases/fourslash/completionsTriggerCharacter.ts new file mode 100644 index 00000000000..06e2a123c52 --- /dev/null +++ b/tests/cases/fourslash/completionsTriggerCharacter.ts @@ -0,0 +1,39 @@ +/// + +// @jsx: preserve + +////const x: "a" | "b" = "/*openQuote*/"/*closeQuote*/; +////const y: 'a' | 'b' = '/*openSingleQuote*/'/*closeSingleQuote*/; +////const z: 'a' | 'b' = `/*openTemplate*/`/*closeTemplate*/; +////const q: "`a`" | "`b`" = "`/*openTemplateInQuote*/a`/*closeTemplateInQuote*/"; + +////// "/*quoteInComment*/ Date: Fri, 20 Apr 2018 10:41:58 -0700 Subject: [PATCH 150/229] Fix assert in getjsdochost (#23575) * Fix assert in getJSDocHost * Update public API to add wider type * Remove now-unnecessary type assertion --- src/compiler/types.ts | 2 +- src/compiler/utilities.ts | 3 + .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- ...docTemplateConstructorFunction2.errors.txt | 28 +++++++ .../jsdocTemplateConstructorFunction2.symbols | 56 ++++++++++++++ .../jsdocTemplateConstructorFunction2.types | 74 +++++++++++++++++++ .../jsdocTemplateConstructorFunction2.ts | 26 +++++++ 8 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt create mode 100644 tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols create mode 100644 tests/baselines/reference/jsdocTemplateConstructorFunction2.types create mode 100644 tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4ea4b7ab8cc..19b3e0bb88a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2332,7 +2332,7 @@ namespace ts { } export interface JSDocTag extends Node { - parent: JSDoc; + parent: JSDoc | JSDocTypeLiteral; atToken: AtToken; tagName: Identifier; comment: string | undefined; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9897d68603e..5c94745f339 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1888,6 +1888,9 @@ namespace ts { } export function getJSDocHost(node: JSDocTag): HasJSDoc { + while (node.parent.kind === SyntaxKind.JSDocTypeLiteral) { + node = node.parent.parent.parent as JSDocParameterTag; + } Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment); return node.parent!.parent!; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0fc77ba2afa..57a3fee2e40 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1494,7 +1494,7 @@ declare namespace ts { comment: string | undefined; } interface JSDocTag extends Node { - parent: JSDoc; + parent: JSDoc | JSDocTypeLiteral; atToken: AtToken; tagName: Identifier; comment: string | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 94ece008de1..076f4f1c57a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1494,7 +1494,7 @@ declare namespace ts { comment: string | undefined; } interface JSDocTag extends Node { - parent: JSDoc; + parent: JSDoc | JSDocTypeLiteral; atToken: AtToken; tagName: Identifier; comment: string | undefined; diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt b/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt new file mode 100644 index 00000000000..db54928b288 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt @@ -0,0 +1,28 @@ +tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(21,1): error TS2322: Type 'false' is not assignable to type 'number'. + + +==== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js (1 errors) ==== + /** + * @template {T} + * @param {T} t + */ + function Zet(t) { + /** @type {T} */ + this.u + this.t = t + } + /** + * @param {T} v + * @param {object} o + * @param {T} o.nested + */ + Zet.prototype.add = function(v, o) { + this.u = v || o.nested + return this.u + } + var z = new Zet(1) + z.t = 2 + z.u = false + ~~~ +!!! error TS2322: Type 'false' is not assignable to type 'number'. + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols new file mode 100644 index 00000000000..1913ee53cdf --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols @@ -0,0 +1,56 @@ +=== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js === +/** + * @template {T} + * @param {T} t + */ +function Zet(t) { +>Zet : Symbol(Zet, Decl(templateTagWithNestedTypeLiteral.js, 0, 0)) +>t : Symbol(t, Decl(templateTagWithNestedTypeLiteral.js, 4, 13)) + + /** @type {T} */ + this.u + this.t = t +>t : Symbol(Zet.t, Decl(templateTagWithNestedTypeLiteral.js, 6, 10)) +>t : Symbol(t, Decl(templateTagWithNestedTypeLiteral.js, 4, 13)) +} +/** + * @param {T} v + * @param {object} o + * @param {T} o.nested + */ +Zet.prototype.add = function(v, o) { +>Zet.prototype : Symbol(Zet.add, Decl(templateTagWithNestedTypeLiteral.js, 8, 1)) +>Zet : Symbol(Zet, Decl(templateTagWithNestedTypeLiteral.js, 0, 0)) +>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --)) +>add : Symbol(Zet.add, Decl(templateTagWithNestedTypeLiteral.js, 8, 1)) +>v : Symbol(v, Decl(templateTagWithNestedTypeLiteral.js, 14, 29)) +>o : Symbol(o, Decl(templateTagWithNestedTypeLiteral.js, 14, 31)) + + this.u = v || o.nested +>this.u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) +>this : Symbol(Zet, Decl(templateTagWithNestedTypeLiteral.js, 0, 0)) +>u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) +>v : Symbol(v, Decl(templateTagWithNestedTypeLiteral.js, 14, 29)) +>o.nested : Symbol(nested, Decl(templateTagWithNestedTypeLiteral.js, 12, 3)) +>o : Symbol(o, Decl(templateTagWithNestedTypeLiteral.js, 14, 31)) +>nested : Symbol(nested, Decl(templateTagWithNestedTypeLiteral.js, 12, 3)) + + return this.u +>this.u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) +>this : Symbol(Zet, Decl(templateTagWithNestedTypeLiteral.js, 0, 0)) +>u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) +} +var z = new Zet(1) +>z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3)) +>Zet : Symbol(Zet, Decl(templateTagWithNestedTypeLiteral.js, 0, 0)) + +z.t = 2 +>z.t : Symbol(Zet.t, Decl(templateTagWithNestedTypeLiteral.js, 6, 10)) +>z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3)) +>t : Symbol(Zet.t, Decl(templateTagWithNestedTypeLiteral.js, 6, 10)) + +z.u = false +>z.u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) +>z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3)) +>u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) + diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.types b/tests/baselines/reference/jsdocTemplateConstructorFunction2.types new file mode 100644 index 00000000000..9f0a55289f3 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.types @@ -0,0 +1,74 @@ +=== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js === +/** + * @template {T} + * @param {T} t + */ +function Zet(t) { +>Zet : typeof Zet +>t : T + + /** @type {T} */ + this.u +>this.u : any +>this : any +>u : any + + this.t = t +>this.t = t : T +>this.t : any +>this : any +>t : any +>t : T +} +/** + * @param {T} v + * @param {object} o + * @param {T} o.nested + */ +Zet.prototype.add = function(v, o) { +>Zet.prototype.add = function(v, o) { this.u = v || o.nested return this.u} : (v: T, o: { nested: T; }) => T +>Zet.prototype.add : any +>Zet.prototype : any +>Zet : typeof Zet +>prototype : any +>add : any +>function(v, o) { this.u = v || o.nested return this.u} : (v: T, o: { nested: T; }) => T +>v : T +>o : { nested: T; } + + this.u = v || o.nested +>this.u = v || o.nested : T +>this.u : T +>this : Zet +>u : T +>v || o.nested : T +>v : T +>o.nested : T +>o : { nested: T; } +>nested : T + + return this.u +>this.u : T +>this : Zet +>u : T +} +var z = new Zet(1) +>z : typeof Zet +>new Zet(1) : typeof Zet +>Zet : typeof Zet +>1 : 1 + +z.t = 2 +>z.t = 2 : 2 +>z.t : number +>z : typeof Zet +>t : number +>2 : 2 + +z.u = false +>z.u = false : false +>z.u : number +>z : typeof Zet +>u : number +>false : false + diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts new file mode 100644 index 00000000000..750126a05b9 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts @@ -0,0 +1,26 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: templateTagWithNestedTypeLiteral.js + +/** + * @template {T} + * @param {T} t + */ +function Zet(t) { + /** @type {T} */ + this.u + this.t = t +} +/** + * @param {T} v + * @param {object} o + * @param {T} o.nested + */ +Zet.prototype.add = function(v, o) { + this.u = v || o.nested + return this.u +} +var z = new Zet(1) +z.t = 2 +z.u = false From 5c94bef0e134ff26c4d03e8fe8190f8b2e760521 Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 20 Apr 2018 13:43:09 -0700 Subject: [PATCH 151/229] Add 'renameFile' command to services (#23573) * Add 'renameFile' command to services * renameFile -> getEditsForFileRename * Support `` directives --- src/compiler/core.ts | 9 +++ src/compiler/moduleNameResolver.ts | 6 ++ src/compiler/program.ts | 10 ++-- src/compiler/types.ts | 2 + src/harness/fourslash.ts | 19 +++++++ src/harness/harnessLanguageService.ts | 3 + src/harness/tsconfig.json | 1 + src/harness/unittests/session.ts | 2 + src/server/client.ts | 4 ++ src/server/protocol.ts | 19 +++++++ src/server/session.ts | 14 ++++- src/server/tsconfig.json | 1 + src/server/tsconfig.library.json | 1 + src/services/codefixes/importFixes.ts | 8 +-- src/services/getEditsForFileRename.ts | 55 +++++++++++++++++++ src/services/services.ts | 11 +++- src/services/textChanges.ts | 6 +- src/services/tsconfig.json | 1 + src/services/types.ts | 1 + src/services/utilities.ts | 8 +++ .../reference/api/tsserverlibrary.d.ts | 17 +++++- tests/baselines/reference/api/typescript.d.ts | 2 + tests/cases/fourslash/fourslash.ts | 5 ++ .../cases/fourslash/getEditsForFileRename.ts | 23 ++++++++ 24 files changed, 211 insertions(+), 17 deletions(-) create mode 100644 src/services/getEditsForFileRename.ts create mode 100644 tests/cases/fourslash/getEditsForFileRename.ts diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 0e53ae2946d..f0220fb8c93 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2212,6 +2212,15 @@ namespace ts { return absolutePath; } + export function getRelativePath(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName) { + const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); + return ensurePathIsRelative(relativePath); + } + + export function ensurePathIsRelative(path: string): string { + return !pathIsRelative(path) ? "./" + path : path; + } + export function getBaseFileName(path: string) { if (path === undefined) { return undefined; diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 0027687c643..81aed522490 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -444,6 +444,12 @@ namespace ts { } } + export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined { + const containingDirectory = getDirectoryPath(containingFile); + const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory); + return perFolderCache && perFolderCache.get(moduleName); + } + export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); if (traceEnabled) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 9eb82661cf5..75cdd07845f 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -622,9 +622,6 @@ namespace ts { Debug.assert(!!missingFilePaths); - // unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks - moduleResolutionCache = undefined; - // Release any files we have acquired in the old program but are // not part of the new program. if (oldProgram && host.onReleaseOldSourceFile) { @@ -670,7 +667,8 @@ namespace ts { sourceFileToPackageName, redirectTargetsSet, isEmittedFile, - getConfigFileParsingDiagnostics + getConfigFileParsingDiagnostics, + getResolvedModuleWithFailedLookupLocationsFromCache, }; verifyCompilerOptions(); @@ -679,6 +677,10 @@ namespace ts { return program; + function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations { + return moduleResolutionCache && resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache); + } + function toPath(fileName: string): Path { return ts.toPath(fileName, currentDirectory, getCanonicalFileName); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 19b3e0bb88a..3b258123651 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2725,6 +2725,8 @@ namespace ts { /* @internal */ redirectTargetsSet: Map; /** Is the file emitted file */ /* @internal */ isEmittedFile(file: string): boolean; + + /* @internal */ getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined; } /* @internal */ diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f65681909fa..643a39e5e68 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3280,6 +3280,15 @@ Actual: ${stringify(fullActual)}`); private static textSpansEqual(a: ts.TextSpan, b: ts.TextSpan) { return a && b && a.start === b.start && a.length === b.length; } + + public getEditsForFileRename(options: FourSlashInterface.GetEditsForFileRenameOptions): void { + const changes = this.languageService.getEditsForFileRename(options.oldPath, options.newPath, this.formatCodeSettings); + this.applyChanges(changes); + for (const fileName in options.newFileContents) { + this.openFile(fileName); + this.verifyCurrentFileContent(options.newFileContents[fileName]); + } + } } export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) { @@ -4371,6 +4380,10 @@ namespace FourSlashInterface { public allRangesAppearInImplementationList(markerName: string) { this.state.verifyRangesInImplementationList(markerName); } + + public getEditsForFileRename(options: GetEditsForFileRenameOptions) { + this.state.getEditsForFileRename(options); + } } export class Edit { @@ -4713,4 +4726,10 @@ namespace FourSlashInterface { range?: FourSlash.Range; code: number; } + + export interface GetEditsForFileRenameOptions { + readonly oldPath: string; + readonly newPath: string; + readonly newFileContents: { readonly [fileName: string]: string }; + } } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 17788f6251d..0063a4730f1 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -528,6 +528,9 @@ namespace Harness.LanguageService { organizeImports(_scope: ts.OrganizeImportsScope, _formatOptions: ts.FormatCodeSettings): ReadonlyArray { throw new Error("Not supported on the shim."); } + getEditsForFileRename(): ReadonlyArray { + throw new Error("Not supported on the shim."); + } getEmitOutput(fileName: string): ts.EmitOutput { return unwrapJSONCallResult(this.shim.getEmitOutput(fileName)); } diff --git a/src/harness/tsconfig.json b/src/harness/tsconfig.json index 3ad653403cf..a4ad8cb3797 100644 --- a/src/harness/tsconfig.json +++ b/src/harness/tsconfig.json @@ -70,6 +70,7 @@ "../services/navigateTo.ts", "../services/navigationBar.ts", "../services/organizeImports.ts", + "../services/getEditsForFileRename.ts", "../services/outliningElementsCollector.ts", "../services/patternMatcher.ts", "../services/preProcess.ts", diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index a892d28808c..25df6f72ea6 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -263,6 +263,8 @@ namespace ts.server { CommandNames.GetEditsForRefactorFull, CommandNames.OrganizeImports, CommandNames.OrganizeImportsFull, + CommandNames.GetEditsForFileRename, + CommandNames.GetEditsForFileRenameFull, ]; it("should not throw when commands are executed with invalid arguments", () => { diff --git a/src/server/client.ts b/src/server/client.ts index 2238734e90c..d7a83ee5320 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -632,6 +632,10 @@ namespace ts.server { return notImplemented(); } + getEditsForFileRename() { + return notImplemented(); + } + private convertCodeEditsToTextChanges(edits: protocol.FileCodeEdits[]): FileTextChanges[] { return edits.map(edit => { const fileName = edit.fileName; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 55ad2a6c36b..5ab62a1c33f 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -121,6 +121,9 @@ namespace ts.server.protocol { OrganizeImports = "organizeImports", /* @internal */ OrganizeImportsFull = "organizeImports-full", + GetEditsForFileRename = "getEditsForFileRename", + /* @internal */ + GetEditsForFileRenameFull = "getEditsForFileRename-full", // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`. } @@ -610,6 +613,22 @@ namespace ts.server.protocol { edits: ReadonlyArray; } + export interface GetEditsForFileRenameRequest extends Request { + command: CommandTypes.GetEditsForFileRename; + arguments: GetEditsForFileRenameRequestArgs; + } + + // Note: The file from FileRequestArgs is just any file in the project. + // We will generate code changes for every file in that project, so the choice is arbitrary. + export interface GetEditsForFileRenameRequestArgs extends FileRequestArgs { + readonly oldFilePath: string; + readonly newFilePath: string; + } + + export interface GetEditsForFileRenameResponse extends Response { + edits: ReadonlyArray; + } + /** * Request for the available codefixes at a specific position. */ diff --git a/src/server/session.ts b/src/server/session.ts index 363369c4057..19a9ee00772 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1665,6 +1665,12 @@ namespace ts.server { } } + private getEditsForFileRename(args: protocol.GetEditsForFileRenameRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { + const { file, project } = this.getFileAndProject(args); + const changes = project.getLanguageService().getEditsForFileRename(args.oldFilePath, args.newFilePath, this.getFormatOptions(file)); + return simplifiedResult ? this.mapTextChangesToCodeEdits(project, changes) : changes; + } + private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { if (args.errorCodes.length === 0) { return undefined; @@ -2118,7 +2124,13 @@ namespace ts.server { }, [CommandNames.OrganizeImportsFull]: (request: protocol.OrganizeImportsRequest) => { return this.requiredResponse(this.organizeImports(request.arguments, /*simplifiedResult*/ false)); - } + }, + [CommandNames.GetEditsForFileRename]: (request: protocol.GetEditsForFileRenameRequest) => { + return this.requiredResponse(this.getEditsForFileRename(request.arguments, /*simplifiedResult*/ true)); + }, + [CommandNames.GetEditsForFileRenameFull]: (request: protocol.GetEditsForFileRenameRequest) => { + return this.requiredResponse(this.getEditsForFileRename(request.arguments, /*simplifiedResult*/ false)); + }, }); public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) { diff --git a/src/server/tsconfig.json b/src/server/tsconfig.json index dc732604ab6..e6768f4edee 100644 --- a/src/server/tsconfig.json +++ b/src/server/tsconfig.json @@ -66,6 +66,7 @@ "../services/navigateTo.ts", "../services/navigationBar.ts", "../services/organizeImports.ts", + "../services/getEditsForFileRename.ts", "../services/outliningElementsCollector.ts", "../services/patternMatcher.ts", "../services/preProcess.ts", diff --git a/src/server/tsconfig.library.json b/src/server/tsconfig.library.json index dd0196fab76..a167d3b39a2 100644 --- a/src/server/tsconfig.library.json +++ b/src/server/tsconfig.library.json @@ -72,6 +72,7 @@ "../services/navigateTo.ts", "../services/navigationBar.ts", "../services/organizeImports.ts", + "../services/getEditsForFileRename.ts", "../services/outliningElementsCollector.ts", "../services/patternMatcher.ts", "../services/preProcess.ts", diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index ddd530e4246..5a10f2f48a7 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -39,7 +39,6 @@ namespace ts.codefix { } function convertToImportCodeFixContext(context: CodeFixContext, symbolToken: Node, symbolName: string): ImportCodeFixContext { - const useCaseSensitiveFileNames = context.host.useCaseSensitiveFileNames ? context.host.useCaseSensitiveFileNames() : false; const { program } = context; const checker = program.getTypeChecker(); @@ -51,7 +50,7 @@ namespace ts.codefix { checker, compilerOptions: program.getCompilerOptions(), cachedImportDeclarations: [], - getCanonicalFileName: createGetCanonicalFileName(useCaseSensitiveFileNames), + getCanonicalFileName: createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(context.host)), symbolName, symbolToken, preferences: context.preferences, @@ -547,11 +546,6 @@ namespace ts.codefix { return startsWith(path, ".."); } - function getRelativePath(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName) { - const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - return !pathIsRelative(relativePath) ? "./" + relativePath : relativePath; - } - function getCodeActionsForAddImport( exportInfos: ReadonlyArray, ctx: ImportCodeFixContext, diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts new file mode 100644 index 00000000000..60fbd5b70f3 --- /dev/null +++ b/src/services/getEditsForFileRename.ts @@ -0,0 +1,55 @@ +/* @internal */ +namespace ts { + export function getEditsForFileRename(program: Program, oldFilePath: string, newFilePath: string, host: LanguageServiceHost, formatContext: formatting.FormatContext): ReadonlyArray { + const pathUpdater = getPathUpdater(oldFilePath, newFilePath, host); + return textChanges.ChangeTracker.with({ host, formatContext }, changeTracker => { + for (const { sourceFile, toUpdate } of getImportsToUpdate(program, oldFilePath)) { + const newPath = pathUpdater(isRef(toUpdate) ? toUpdate.fileName : toUpdate.text); + if (newPath !== undefined) { + const range = isRef(toUpdate) ? toUpdate : createTextRange(toUpdate.getStart(sourceFile) + 1, toUpdate.end - 1); + changeTracker.replaceRangeWithText(sourceFile, range, isRef(toUpdate) ? newPath : removeFileExtension(newPath)); + } + } + }); + } + + interface ToUpdate { + readonly sourceFile: SourceFile; + readonly toUpdate: StringLiteralLike | FileReference; + } + function isRef(toUpdate: StringLiteralLike | FileReference): toUpdate is FileReference { + return "fileName" in toUpdate; + } + + function getImportsToUpdate(program: Program, oldFilePath: string): ReadonlyArray { + const checker = program.getTypeChecker(); + const result: ToUpdate[] = []; + for (const sourceFile of program.getSourceFiles()) { + for (const ref of sourceFile.referencedFiles) { + if (!program.getSourceFileFromReference(sourceFile, ref) && resolveTripleslashReference(ref.fileName, sourceFile.fileName) === oldFilePath) { + result.push({ sourceFile, toUpdate: ref }); + } + } + + for (const importStringLiteral of sourceFile.imports) { + // If it resolved to something already, ignore. + if (checker.getSymbolAtLocation(importStringLiteral)) continue; + + const resolved = program.getResolvedModuleWithFailedLookupLocationsFromCache(importStringLiteral.text, sourceFile.fileName); + if (contains(resolved.failedLookupLocations, oldFilePath)) { + result.push({ sourceFile, toUpdate: importStringLiteral }); + } + } + } + return result; + } + + function getPathUpdater(oldFilePath: string, newFilePath: string, host: LanguageServiceHost): (oldPath: string) => string | undefined { + // Get the relative path from old to new location, and append it on to the end of imports and normalize. + const rel = getRelativePath(newFilePath, getDirectoryPath(oldFilePath), createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host))); + return oldPath => { + if (!pathIsRelative(oldPath)) return; + return ensurePathIsRelative(normalizePath(combinePaths(getDirectoryPath(oldPath), rel))); + }; + } +} diff --git a/src/services/services.ts b/src/services/services.ts index d395f1cdbc0..08e3c960d7a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1128,7 +1128,6 @@ namespace ts { let lastProjectVersion: string; let lastTypesRootVersion = 0; - const useCaseSensitivefileNames = host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(); const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); const currentDirectory = host.getCurrentDirectory(); @@ -1145,7 +1144,8 @@ namespace ts { } } - const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames); + const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host); + const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); function getValidSourceFile(fileName: string): SourceFile { const sourceFile = program.getSourceFile(fileName); @@ -1202,7 +1202,7 @@ namespace ts { getSourceFileByPath: getOrCreateSourceFileByPath, getCancellationToken: () => cancellationToken, getCanonicalFileName, - useCaseSensitiveFileNames: () => useCaseSensitivefileNames, + useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, getNewLine: () => getNewLineCharacter(newSettings, () => getNewLineOrDefaultFromHost(host)), getDefaultLibFileName: (options) => host.getDefaultLibFileName(options), writeFile: noop, @@ -1951,6 +1951,10 @@ namespace ts { return OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences); } + function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray { + return ts.getEditsForFileRename(getProgram(), oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions)); + } + function applyCodeActionCommand(action: CodeActionCommand): Promise; function applyCodeActionCommand(action: CodeActionCommand[]): Promise; function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise; @@ -2251,6 +2255,7 @@ namespace ts { getCombinedCodeFix, applyCodeActionCommand, organizeImports, + getEditsForFileRename, getEmitOutput, getNonBoundSourceFile, getSourceFile, diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index b54caf402b1..4f431e28e0e 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -365,8 +365,12 @@ namespace ts.textChanges { this.insertText(sourceFile, token.getStart(sourceFile), text); } + public replaceRangeWithText(sourceFile: SourceFile, range: TextRange, text: string) { + this.changes.push({ kind: ChangeKind.Text, sourceFile, range, text }); + } + private insertText(sourceFile: SourceFile, pos: number, text: string): void { - this.changes.push({ kind: ChangeKind.Text, sourceFile, range: { pos, end: pos }, text }); + this.replaceRangeWithText(sourceFile, createTextRange(pos), text); } /** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */ diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 31b35a44271..75b46a5c49b 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -63,6 +63,7 @@ "navigateTo.ts", "navigationBar.ts", "organizeImports.ts", + "getEditsForFileRename.ts", "outliningElementsCollector.ts", "patternMatcher.ts", "preProcess.ts", diff --git a/src/services/types.ts b/src/services/types.ts index 1c4a38b10c6..e835d0cdef6 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -334,6 +334,7 @@ namespace ts { getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; + getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 63170678202..cd87824e7d6 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1213,6 +1213,14 @@ namespace ts { ? isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined : getTextOfIdentifierOrLiteral(name); } + + export function hostUsesCaseSensitiveFileNames(host: LanguageServiceHost): boolean { + return host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false; + } + + export function hostGetCanonicalFileName(host: LanguageServiceHost): GetCanonicalFileName { + return createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host)); + } } // Display-part writer helpers diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 57a3fee2e40..554c6da34d1 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3402,6 +3402,7 @@ declare namespace ts { set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void; } function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache; + function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined; function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations; function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations; function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations; @@ -4446,6 +4447,7 @@ declare namespace ts { getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; + getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; getProgram(): Program; dispose(): void; @@ -5410,7 +5412,8 @@ declare namespace ts.server.protocol { GetSupportedCodeFixes = "getSupportedCodeFixes", GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", - OrganizeImports = "organizeImports" + OrganizeImports = "organizeImports", + GetEditsForFileRename = "getEditsForFileRename" } /** * A TypeScript Server message @@ -5806,6 +5809,17 @@ declare namespace ts.server.protocol { interface OrganizeImportsResponse extends Response { edits: ReadonlyArray; } + interface GetEditsForFileRenameRequest extends Request { + command: CommandTypes.GetEditsForFileRename; + arguments: GetEditsForFileRenameRequestArgs; + } + interface GetEditsForFileRenameRequestArgs extends FileRequestArgs { + readonly oldFilePath: string; + readonly newFilePath: string; + } + interface GetEditsForFileRenameResponse extends Response { + edits: ReadonlyArray; + } /** * Request for the available codefixes at a specific position. */ @@ -8322,6 +8336,7 @@ declare namespace ts.server { private getApplicableRefactors; private getEditsForRefactor; private organizeImports; + private getEditsForFileRename; private getCodeFixes; private getCombinedCodeFix; private applyCodeActionCommand; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 076f4f1c57a..416be7254b0 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3402,6 +3402,7 @@ declare namespace ts { set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void; } function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache; + function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined; function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations; function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations; function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations; @@ -4446,6 +4447,7 @@ declare namespace ts { getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; + getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; getProgram(): Program; dispose(): void; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index c4ef61f44c8..42dee74bb03 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -345,6 +345,11 @@ declare namespace FourSlashInterface { getSuggestionDiagnostics(expected: ReadonlyArray): void; ProjectInfo(expected: string[]): void; allRangesAppearInImplementationList(markerName: string): void; + getEditsForFileRename(options: { + oldPath: string; + newPath: string; + newFileContents: { [fileName: string]: string }; + }); } class edit { backspace(count?: number): void; diff --git a/tests/cases/fourslash/getEditsForFileRename.ts b/tests/cases/fourslash/getEditsForFileRename.ts new file mode 100644 index 00000000000..b000ce28dd8 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /a.ts +/////// +////import old from "./src/old"; + +// @Filename: /src/a.ts +/////// +////import old from "./old"; + +// @Filename: /src/foo/a.ts +/////// +////import old from "../old"; + +verify.getEditsForFileRename({ + oldPath: "/src/old.ts", + newPath: "/src/new.ts", + newFileContents: { + "/a.ts": '/// \nimport old from "./src/new";', + "/src/a.ts": '/// \nimport old from "./new";', + "/src/foo/a.ts": '/// \nimport old from "../new";', + }, +}); From 699ea246ffbc03e3afb80f58476348daeb1cbe4c Mon Sep 17 00:00:00 2001 From: Andy Date: Fri, 20 Apr 2018 15:02:18 -0700 Subject: [PATCH 152/229] Skip arrow functions in checkAndReportErrorForMissingPrefix (#23584) --- src/compiler/checker.ts | 2 +- .../classMemberInitializerWithLamdaScoping4.errors.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c1cb7166015..f0d13cacf51 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1568,7 +1568,7 @@ namespace ts { return false; } - const container = getThisContainer(errorLocation, /*includeArrowFunctions*/ true); + const container = getThisContainer(errorLocation, /*includeArrowFunctions*/ false); let location = container; while (location) { if (isClassLike(location.parent)) { diff --git a/tests/baselines/reference/classMemberInitializerWithLamdaScoping4.errors.txt b/tests/baselines/reference/classMemberInitializerWithLamdaScoping4.errors.txt index 58a660c1ee8..03aa27e91f8 100644 --- a/tests/baselines/reference/classMemberInitializerWithLamdaScoping4.errors.txt +++ b/tests/baselines/reference/classMemberInitializerWithLamdaScoping4.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/classMemberInitializerWithLamdaScoping3_1.ts(8,21): error TS2304: Cannot find name 'field1'. +tests/cases/compiler/classMemberInitializerWithLamdaScoping3_1.ts(8,21): error TS2663: Cannot find name 'field1'. Did you mean the instance member 'this.field1'? ==== tests/cases/compiler/classMemberInitializerWithLamdaScoping3_0.ts (0 errors) ==== @@ -14,6 +14,6 @@ tests/cases/compiler/classMemberInitializerWithLamdaScoping3_1.ts(8,21): error T messageHandler = () => { console.log(field1); // Should be error that couldnt find symbol field1 ~~~~~~ -!!! error TS2304: Cannot find name 'field1'. +!!! error TS2663: Cannot find name 'field1'. Did you mean the instance member 'this.field1'? }; } \ No newline at end of file From ec0e04f85346bc7d224341182b4bf0a25f93be0d Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 20 Apr 2018 22:10:46 +0000 Subject: [PATCH 153/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- 4 files changed, 56 insertions(+), 128 deletions(-) diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index b2ffdf585e0..5798b852bbe 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -900,6 +900,12 @@ + + + + + + @@ -996,24 +1002,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2385,15 +2376,6 @@ - - - - - - - - - @@ -3768,20 +3750,20 @@ - + - + - + - + - + - + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3252fe24f15..5be5577f3a8 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -893,6 +893,12 @@ + + + + + + @@ -989,24 +995,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2378,15 +2369,6 @@ - - - - - - - - - @@ -3761,20 +3743,20 @@ - + - + - + - + - + - + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index 07d26979bf8..dc4c01fcad4 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -902,6 +902,12 @@ + + + + + + @@ -998,24 +1004,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2387,15 +2378,6 @@ - - - - - - - - - @@ -3770,20 +3752,20 @@ - + - + - + - + - + - + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 72116417c1b..5899715db8b 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -896,6 +896,12 @@ + + + + + + @@ -992,24 +998,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2381,15 +2372,6 @@ - - - - - - - - - @@ -3764,20 +3746,20 @@ - + - + - + - + - + - + From 1e1b72892c11e938b3b6d518cd72c2609ffda16a Mon Sep 17 00:00:00 2001 From: kingwl Date: Sat, 21 Apr 2018 12:06:29 +0800 Subject: [PATCH 154/229] accept baseline --- ...ConstantMemberWithStringEmitDeclaration.js | 82 ++++++++++++++++++ ...antMemberWithStringEmitDeclaration.symbols | 58 +++++++++++++ ...stantMemberWithStringEmitDeclaration.types | 83 +++++++++++++++++++ ...ConstantMemberWithStringEmitDeclaration.ts | 29 +++++++ 4 files changed, 252 insertions(+) create mode 100644 tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.js create mode 100644 tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.symbols create mode 100644 tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.types create mode 100644 tests/cases/conformance/enums/enumConstantMemberWithStringEmitDeclaration.ts diff --git a/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.js b/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.js new file mode 100644 index 00000000000..d78ce824256 --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.js @@ -0,0 +1,82 @@ +//// [enumConstantMemberWithStringEmitDeclaration.ts] +enum T1 { + a = "1", + b = "1" + "2", + c = "1" + "2" + "3" +} + +enum T2 { + a = "1", + b = "1" + "2" +} + +enum T3 { + a = "1", + b = "1" + "2" +} + +enum T4 { + a = "1" +} + +enum T5 { + a = "1" + "2" +} + +declare enum T6 { + a = "1", + b = "1" + "2" +} + + +//// [enumConstantMemberWithStringEmitDeclaration.js] +var T1; +(function (T1) { + T1["a"] = "1"; + T1["b"] = "12"; + T1["c"] = "123"; +})(T1 || (T1 = {})); +var T2; +(function (T2) { + T2["a"] = "1"; + T2["b"] = "12"; +})(T2 || (T2 = {})); +var T3; +(function (T3) { + T3["a"] = "1"; + T3["b"] = "12"; +})(T3 || (T3 = {})); +var T4; +(function (T4) { + T4["a"] = "1"; +})(T4 || (T4 = {})); +var T5; +(function (T5) { + T5["a"] = "12"; +})(T5 || (T5 = {})); + + +//// [enumConstantMemberWithStringEmitDeclaration.d.ts] +declare enum T1 { + a = "1", + b = "12", + c = "123" +} +declare enum T2 { + a = "1", + b = "12" +} +declare enum T3 { + a = "1", + b = "12" +} +declare enum T4 { + a = "1" +} +declare enum T5 { + a = "12" +} +declare enum T6 { + a = "1", + b = "12" +} diff --git a/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.symbols b/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.symbols new file mode 100644 index 00000000000..1bb70c7882b --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.symbols @@ -0,0 +1,58 @@ +=== tests/cases/conformance/enums/enumConstantMemberWithStringEmitDeclaration.ts === +enum T1 { +>T1 : Symbol(T1, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 0, 0)) + + a = "1", +>a : Symbol(T1.a, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 0, 9)) + + b = "1" + "2", +>b : Symbol(T1.b, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 1, 12)) + + c = "1" + "2" + "3" +>c : Symbol(T1.c, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 2, 18)) +} + +enum T2 { +>T2 : Symbol(T2, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 4, 1)) + + a = "1", +>a : Symbol(T2.a, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 6, 9)) + + b = "1" + "2" +>b : Symbol(T2.b, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 7, 12)) +} + +enum T3 { +>T3 : Symbol(T3, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 9, 1)) + + a = "1", +>a : Symbol(T3.a, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 11, 9)) + + b = "1" + "2" +>b : Symbol(T3.b, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 12, 12)) +} + +enum T4 { +>T4 : Symbol(T4, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 14, 1)) + + a = "1" +>a : Symbol(T4.a, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 16, 9)) +} + +enum T5 { +>T5 : Symbol(T5, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 18, 1)) + + a = "1" + "2" +>a : Symbol(T5.a, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 20, 9)) +} + +declare enum T6 { +>T6 : Symbol(T6, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 22, 1)) + + a = "1", +>a : Symbol(T6.a, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 24, 17)) + + b = "1" + "2" +>b : Symbol(T6.b, Decl(enumConstantMemberWithStringEmitDeclaration.ts, 25, 12)) +} + diff --git a/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.types b/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.types new file mode 100644 index 00000000000..b613ec306e4 --- /dev/null +++ b/tests/baselines/reference/enumConstantMemberWithStringEmitDeclaration.types @@ -0,0 +1,83 @@ +=== tests/cases/conformance/enums/enumConstantMemberWithStringEmitDeclaration.ts === +enum T1 { +>T1 : T1 + + a = "1", +>a : T1.a +>"1" : "1" + + b = "1" + "2", +>b : T1.b +>"1" + "2" : string +>"1" : "1" +>"2" : "2" + + c = "1" + "2" + "3" +>c : T1.c +>"1" + "2" + "3" : string +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +>"3" : "3" +} + +enum T2 { +>T2 : T2 + + a = "1", +>a : T2.a +>"1" : "1" + + b = "1" + "2" +>b : T2.b +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +} + +enum T3 { +>T3 : T3 + + a = "1", +>a : T3.a +>"1" : "1" + + b = "1" + "2" +>b : T3.b +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +} + +enum T4 { +>T4 : T4 + + a = "1" +>a : T4 +>"1" : "1" +} + +enum T5 { +>T5 : T5 + + a = "1" + "2" +>a : T5 +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +} + +declare enum T6 { +>T6 : T6 + + a = "1", +>a : T6.a +>"1" : "1" + + b = "1" + "2" +>b : T6.b +>"1" + "2" : string +>"1" : "1" +>"2" : "2" +} + diff --git a/tests/cases/conformance/enums/enumConstantMemberWithStringEmitDeclaration.ts b/tests/cases/conformance/enums/enumConstantMemberWithStringEmitDeclaration.ts new file mode 100644 index 00000000000..37667dca79c --- /dev/null +++ b/tests/cases/conformance/enums/enumConstantMemberWithStringEmitDeclaration.ts @@ -0,0 +1,29 @@ +// @declaration: true +enum T1 { + a = "1", + b = "1" + "2", + c = "1" + "2" + "3" +} + +enum T2 { + a = "1", + b = "1" + "2" +} + +enum T3 { + a = "1", + b = "1" + "2" +} + +enum T4 { + a = "1" +} + +enum T5 { + a = "1" + "2" +} + +declare enum T6 { + a = "1", + b = "1" + "2" +} From 5b2f4ac38020e0acfcddeeb446f4bbc386f0db56 Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 21 Apr 2018 04:10:23 +0000 Subject: [PATCH 155/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index efac12c6e66..23b68db43f8 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -903,6 +903,12 @@ + + + + + + @@ -999,24 +1005,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2388,15 +2379,6 @@ - - - - - - - - - @@ -3771,20 +3753,20 @@ - + - + - + - + - + - + From cb96e3fad5e7e1adb1f0806cc24bde90fede6249 Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 21 Apr 2018 10:10:32 +0000 Subject: [PATCH 156/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 46 ++++++------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 259d4b3b90e..6b949870bbd 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -912,6 +912,12 @@ + + + + + + @@ -1008,24 +1014,9 @@ - + - - - - - - - - - - - - - - - - + @@ -2397,15 +2388,6 @@ - - - - - - - - - @@ -3780,20 +3762,20 @@ - + - + - + - + - + - + From 652e4932f6db92ca6dc3c2b112b1b28733db5529 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 21 Apr 2018 09:32:46 -0700 Subject: [PATCH 157/229] Address CR feedback --- src/compiler/checker.ts | 8 ++++---- src/compiler/types.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index af069d548a7..7963614789d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5629,7 +5629,7 @@ namespace ts { * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ - function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: UnderscoreEscapedMap, decl: LateBoundDeclaration) { + function lateBindMember(parent: Symbol, earlySymbols: SymbolTable | undefined, lateSymbols: SymbolTable, decl: LateBoundDeclaration) { Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); const links = getNodeLinks(decl); if (!links.resolvedSymbol) { @@ -5686,7 +5686,7 @@ namespace ts { links[resolutionKind] = earlySymbols || emptySymbols; // fill in any as-yet-unresolved late-bound members. - const lateSymbols = createMap() as UnderscoreEscapedMap; + const lateSymbols = createSymbolTable(); for (const decl of symbol.declarations) { const members = getMembersOfDeclaration(decl); if (members) { @@ -6606,8 +6606,8 @@ namespace ts { } else { if (type !== commonType) { - checkFlags |= CheckFlags.HasNonUniformType; - } + checkFlags |= CheckFlags.HasNonUniformType; + } } propTypes.push(type); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4db1c342098..f288d0f8c59 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3369,11 +3369,11 @@ namespace ts { members?: SymbolTable; // Class, interface or object literal instance members exports?: SymbolTable; // Module exports globalExports?: SymbolTable; // Conditional global UMD exports - nameType?: Type; // Type associated with a late-bound symbol /* @internal */ id?: number; // Unique id (used to look up SymbolLinks) /* @internal */ mergeId?: number; // Merge id (used to look up merged symbol) /* @internal */ parent?: Symbol; // Parent symbol /* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol + /* @internal */ nameType?: Type; // Type associated with a late-bound symbol /* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums /* @internal */ isReferenced?: SymbolFlags; // True if the symbol is referenced elsewhere. Keeps track of the meaning of a reference in case a symbol is both a type parameter and parameter. /* @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol? From c7f55be90c31fbdbaaecb6612b76a2f0b1319465 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 21 Apr 2018 09:32:54 -0700 Subject: [PATCH 158/229] Accept new baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 - tests/baselines/reference/api/typescript.d.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1c16c71cc99..ae19b8c7e2f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2020,7 +2020,6 @@ declare namespace ts { members?: SymbolTable; exports?: SymbolTable; globalExports?: SymbolTable; - nameType?: Type; } enum InternalSymbolName { Call = "__call", diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 7c23f93e038..5f4ca22f8cc 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2020,7 +2020,6 @@ declare namespace ts { members?: SymbolTable; exports?: SymbolTable; globalExports?: SymbolTable; - nameType?: Type; } enum InternalSymbolName { Call = "__call", From eb112ab492c26c6346ea587646dd617093e72b78 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Sat, 21 Apr 2018 12:50:05 -0700 Subject: [PATCH 159/229] Deduplicate declarations in combined type/value symbols (#23593) --- src/compiler/checker.ts | 6 ++-- ...aliasDoesNotDuplicateSignatures.errors.txt | 21 ++++++++++++ .../aliasDoesNotDuplicateSignatures.js | 23 +++++++++++++ .../aliasDoesNotDuplicateSignatures.symbols | 32 +++++++++++++++++++ .../aliasDoesNotDuplicateSignatures.types | 32 +++++++++++++++++++ .../aliasDoesNotDuplicateSignatures.ts | 13 ++++++++ 6 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/aliasDoesNotDuplicateSignatures.errors.txt create mode 100644 tests/baselines/reference/aliasDoesNotDuplicateSignatures.js create mode 100644 tests/baselines/reference/aliasDoesNotDuplicateSignatures.symbols create mode 100644 tests/baselines/reference/aliasDoesNotDuplicateSignatures.types create mode 100644 tests/cases/compiler/aliasDoesNotDuplicateSignatures.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8d37b888178..99b3420131f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1841,7 +1841,7 @@ namespace ts { return valueSymbol; } const result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName); - result.declarations = concatenate(valueSymbol.declarations, typeSymbol.declarations); + result.declarations = deduplicate(concatenate(valueSymbol.declarations, typeSymbol.declarations), equateValues); result.parent = valueSymbol.parent || typeSymbol.parent; if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration; if (typeSymbol.members) result.members = typeSymbol.members; @@ -1876,7 +1876,7 @@ namespace ts { let symbolFromVariable: Symbol; // First check if module was specified with "export=". If so, get the member from the resolved type - if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=" as __String)) { + if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get(InternalSymbolName.ExportEquals)) { symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText); } else { @@ -1889,7 +1889,7 @@ namespace ts { if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === InternalSymbolName.Default) { symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); } - const symbol = symbolFromModule && symbolFromVariable ? + const symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { diff --git a/tests/baselines/reference/aliasDoesNotDuplicateSignatures.errors.txt b/tests/baselines/reference/aliasDoesNotDuplicateSignatures.errors.txt new file mode 100644 index 00000000000..38e2c8cfe17 --- /dev/null +++ b/tests/baselines/reference/aliasDoesNotDuplicateSignatures.errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/user.ts(3,5): error TS2322: Type '() => void' is not assignable to type 'string'. +tests/cases/compiler/user.ts(4,5): error TS2322: Type '() => void' is not assignable to type 'string'. + + +==== tests/cases/compiler/demo.d.ts (0 errors) ==== + declare namespace demoNS { + function f(): void; + } + declare module 'demoModule' { + import alias = demoNS; + export = alias; + } +==== tests/cases/compiler/user.ts (2 errors) ==== + import { f } from 'demoModule'; + // Assign an incorrect type here to see the type of 'f'. + let x1: string = demoNS.f; + ~~ +!!! error TS2322: Type '() => void' is not assignable to type 'string'. + let x2: string = f; + ~~ +!!! error TS2322: Type '() => void' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/aliasDoesNotDuplicateSignatures.js b/tests/baselines/reference/aliasDoesNotDuplicateSignatures.js new file mode 100644 index 00000000000..0ae878bebc5 --- /dev/null +++ b/tests/baselines/reference/aliasDoesNotDuplicateSignatures.js @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/aliasDoesNotDuplicateSignatures.ts] //// + +//// [demo.d.ts] +declare namespace demoNS { + function f(): void; +} +declare module 'demoModule' { + import alias = demoNS; + export = alias; +} +//// [user.ts] +import { f } from 'demoModule'; +// Assign an incorrect type here to see the type of 'f'. +let x1: string = demoNS.f; +let x2: string = f; + +//// [user.js] +"use strict"; +exports.__esModule = true; +var demoModule_1 = require("demoModule"); +// Assign an incorrect type here to see the type of 'f'. +var x1 = demoNS.f; +var x2 = demoModule_1.f; diff --git a/tests/baselines/reference/aliasDoesNotDuplicateSignatures.symbols b/tests/baselines/reference/aliasDoesNotDuplicateSignatures.symbols new file mode 100644 index 00000000000..21ae7940f96 --- /dev/null +++ b/tests/baselines/reference/aliasDoesNotDuplicateSignatures.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/demo.d.ts === +declare namespace demoNS { +>demoNS : Symbol(demoNS, Decl(demo.d.ts, 0, 0)) + + function f(): void; +>f : Symbol(f, Decl(demo.d.ts, 0, 26)) +} +declare module 'demoModule' { +>'demoModule' : Symbol('demoModule', Decl(demo.d.ts, 2, 1)) + + import alias = demoNS; +>alias : Symbol(alias, Decl(demo.d.ts, 3, 29)) +>demoNS : Symbol(alias, Decl(demo.d.ts, 0, 0)) + + export = alias; +>alias : Symbol(alias, Decl(demo.d.ts, 3, 29)) +} +=== tests/cases/compiler/user.ts === +import { f } from 'demoModule'; +>f : Symbol(f, Decl(user.ts, 0, 8)) + +// Assign an incorrect type here to see the type of 'f'. +let x1: string = demoNS.f; +>x1 : Symbol(x1, Decl(user.ts, 2, 3)) +>demoNS.f : Symbol(f, Decl(demo.d.ts, 0, 26)) +>demoNS : Symbol(demoNS, Decl(demo.d.ts, 0, 0)) +>f : Symbol(f, Decl(demo.d.ts, 0, 26)) + +let x2: string = f; +>x2 : Symbol(x2, Decl(user.ts, 3, 3)) +>f : Symbol(f, Decl(user.ts, 0, 8)) + diff --git a/tests/baselines/reference/aliasDoesNotDuplicateSignatures.types b/tests/baselines/reference/aliasDoesNotDuplicateSignatures.types new file mode 100644 index 00000000000..ada54494a83 --- /dev/null +++ b/tests/baselines/reference/aliasDoesNotDuplicateSignatures.types @@ -0,0 +1,32 @@ +=== tests/cases/compiler/demo.d.ts === +declare namespace demoNS { +>demoNS : typeof demoNS + + function f(): void; +>f : () => void +} +declare module 'demoModule' { +>'demoModule' : typeof 'demoModule' + + import alias = demoNS; +>alias : typeof alias +>demoNS : typeof alias + + export = alias; +>alias : typeof alias +} +=== tests/cases/compiler/user.ts === +import { f } from 'demoModule'; +>f : () => void + +// Assign an incorrect type here to see the type of 'f'. +let x1: string = demoNS.f; +>x1 : string +>demoNS.f : () => void +>demoNS : typeof demoNS +>f : () => void + +let x2: string = f; +>x2 : string +>f : () => void + diff --git a/tests/cases/compiler/aliasDoesNotDuplicateSignatures.ts b/tests/cases/compiler/aliasDoesNotDuplicateSignatures.ts new file mode 100644 index 00000000000..fcae45f3dc1 --- /dev/null +++ b/tests/cases/compiler/aliasDoesNotDuplicateSignatures.ts @@ -0,0 +1,13 @@ +// @filename: demo.d.ts +declare namespace demoNS { + function f(): void; +} +declare module 'demoModule' { + import alias = demoNS; + export = alias; +} +// @filename: user.ts +import { f } from 'demoModule'; +// Assign an incorrect type here to see the type of 'f'. +let x1: string = demoNS.f; +let x2: string = f; \ No newline at end of file From 2e78d1ef216f54e3eeb47730d8cee297d8fd5629 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 23 Apr 2018 11:11:06 -0700 Subject: [PATCH 160/229] getEditsForFileRename: Update tsconfig "files" (#23625) --- src/harness/fourslash.ts | 8 ++----- src/services/getEditsForFileRename.ts | 23 ++++++++++++++++++- .../cases/fourslash/getEditsForFileRename.ts | 4 ++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 643a39e5e68..44c05f5d019 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -276,14 +276,10 @@ namespace FourSlash { if (configFileName) { const baseDir = ts.normalizePath(ts.getDirectoryPath(configFileName)); const host = new Utils.MockParseConfigHost(baseDir, /*ignoreCase*/ false, this.inputFiles); - - const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName)); - assert.isTrue(configJsonObj.config !== undefined); - - compilationOptions = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir, compilationOptions, configFileName).options; + const jsonSourceFile = ts.parseJsonText(configFileName, this.inputFiles.get(configFileName)); + compilationOptions = ts.parseJsonSourceFileConfigFileContent(jsonSourceFile, host, baseDir, compilationOptions, configFileName).options; } - if (compilationOptions.typeRoots) { compilationOptions.typeRoots = compilationOptions.typeRoots.map(p => ts.getNormalizedAbsolutePath(p, this.basePath)); } diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 60fbd5b70f3..09bbdc11e78 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -3,16 +3,33 @@ namespace ts { export function getEditsForFileRename(program: Program, oldFilePath: string, newFilePath: string, host: LanguageServiceHost, formatContext: formatting.FormatContext): ReadonlyArray { const pathUpdater = getPathUpdater(oldFilePath, newFilePath, host); return textChanges.ChangeTracker.with({ host, formatContext }, changeTracker => { + updateTsconfigFiles(program, changeTracker, oldFilePath, newFilePath); for (const { sourceFile, toUpdate } of getImportsToUpdate(program, oldFilePath)) { const newPath = pathUpdater(isRef(toUpdate) ? toUpdate.fileName : toUpdate.text); if (newPath !== undefined) { - const range = isRef(toUpdate) ? toUpdate : createTextRange(toUpdate.getStart(sourceFile) + 1, toUpdate.end - 1); + const range = isRef(toUpdate) ? toUpdate : createStringRange(toUpdate, sourceFile); changeTracker.replaceRangeWithText(sourceFile, range, isRef(toUpdate) ? newPath : removeFileExtension(newPath)); } } }); } + function updateTsconfigFiles(program: Program, changeTracker: textChanges.ChangeTracker, oldFilePath: string, newFilePath: string): void { + const cfg = program.getCompilerOptions().configFile; + if (!cfg) return; + const oldFile = cfg.jsonObject && getFilesEntry(cfg.jsonObject, oldFilePath); + if (oldFile) { + changeTracker.replaceRangeWithText(cfg, createStringRange(oldFile, cfg), newFilePath); + } + } + + function getFilesEntry(cfg: ObjectLiteralExpression, fileName: string): StringLiteral | undefined { + const filesProp = find(cfg.properties, (prop): prop is PropertyAssignment => + isPropertyAssignment(prop) && isStringLiteral(prop.name) && prop.name.text === "files"); + const files = filesProp && filesProp.initializer; + return files && isArrayLiteralExpression(files) ? find(files.elements, (e): e is StringLiteral => isStringLiteral(e) && e.text === fileName) : undefined; + } + interface ToUpdate { readonly sourceFile: SourceFile; readonly toUpdate: StringLiteralLike | FileReference; @@ -52,4 +69,8 @@ namespace ts { return ensurePathIsRelative(normalizePath(combinePaths(getDirectoryPath(oldPath), rel))); }; } + + function createStringRange(node: StringLiteralLike, sourceFile: SourceFileLike): TextRange { + return createTextRange(node.getStart(sourceFile) + 1, node.end - 1); + } } diff --git a/tests/cases/fourslash/getEditsForFileRename.ts b/tests/cases/fourslash/getEditsForFileRename.ts index b000ce28dd8..f2694818d1d 100644 --- a/tests/cases/fourslash/getEditsForFileRename.ts +++ b/tests/cases/fourslash/getEditsForFileRename.ts @@ -12,6 +12,9 @@ /////// ////import old from "../old"; +// @Filename: /tsconfig.json +////{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/old.ts"] } + verify.getEditsForFileRename({ oldPath: "/src/old.ts", newPath: "/src/new.ts", @@ -19,5 +22,6 @@ verify.getEditsForFileRename({ "/a.ts": '/// \nimport old from "./src/new";', "/src/a.ts": '/// \nimport old from "./new";', "/src/foo/a.ts": '/// \nimport old from "../new";', + "/tsconfig.json": '{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/new.ts"] }', }, }); From 645258cc7db15646a5f66b2a89f5f760b55671a9 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 23 Apr 2018 11:24:51 -0700 Subject: [PATCH 161/229] Allow getting import completion details with misspelled name (#23624) --- src/harness/fourslash.ts | 9 +-------- src/services/completions.ts | 18 +++++++++++++----- ...letionsImport_details_withMisspelledName.ts | 17 +++++++++++++++++ 3 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 tests/cases/fourslash/completionsImport_details_withMisspelledName.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 44c05f5d019..7dfff7dd189 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2419,14 +2419,7 @@ Actual: ${stringify(fullActual)}`); public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) { this.goToMarker(markerName); - const actualCompletion = this.getCompletionListAtCaret({ ...ts.defaultPreferences, includeCompletionsForModuleExports: true }).entries.find(e => - e.name === options.name && e.source === options.source); - - if (!actualCompletion.hasAction) { - this.raiseError(`Completion for ${options.name} does not have an associated action.`); - } - - const details = this.getCompletionEntryDetails(options.name, actualCompletion.source, options.preferences); + const details = this.getCompletionEntryDetails(options.name, options.source, options.preferences); if (details.codeActions.length !== 1) { this.raiseError(`Expected one code action, got ${details.codeActions.length}`); } diff --git a/src/services/completions.ts b/src/services/completions.ts index f887d28cf10..f57f108812c 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -47,7 +47,7 @@ namespace ts.Completions { return getLabelCompletionAtPosition(contextToken.parent); } - const completionData = getCompletionData(program, log, sourceFile, position, preferences); + const completionData = getCompletionData(program, log, sourceFile, position, preferences, /*detailsEntryId*/ undefined); if (!completionData) { return undefined; } @@ -486,9 +486,9 @@ namespace ts.Completions { previousToken: Node; readonly isJsxInitializer: IsJsxInitializer; } - function getSymbolCompletionFromEntryId(program: Program, log: Log, sourceFile: SourceFile, position: number, { name, source }: CompletionEntryIdentifier, + function getSymbolCompletionFromEntryId(program: Program, log: Log, sourceFile: SourceFile, position: number, entryId: CompletionEntryIdentifier, ): SymbolCompletion | { type: "request", request: Request } | { type: "none" } { - const completionData = getCompletionData(program, log, sourceFile, position, { includeCompletionsForModuleExports: true, includeCompletionsWithInsertText: true }); + const completionData = getCompletionData(program, log, sourceFile, position, { includeCompletionsForModuleExports: true, includeCompletionsWithInsertText: true }, entryId); if (!completionData) { return { type: "none" }; } @@ -505,7 +505,9 @@ namespace ts.Completions { return firstDefined(symbols, (symbol): SymbolCompletion => { // TODO: Shouldn't need return type annotation (GH#12632) const origin = symbolToOriginInfoMap[getSymbolId(symbol)]; const info = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, origin, completionKind); - return info && info.name === name && getSourceFromOrigin(origin) === source ? { type: "symbol" as "symbol", symbol, location, symbolToOriginInfoMap, previousToken, isJsxInitializer } : undefined; + return info && info.name === entryId.name && getSourceFromOrigin(origin) === entryId.source + ? { type: "symbol" as "symbol", symbol, location, symbolToOriginInfoMap, previousToken, isJsxInitializer } + : undefined; }) || { type: "none" }; } @@ -755,6 +757,7 @@ namespace ts.Completions { sourceFile: SourceFile, position: number, preferences: Pick, + detailsEntryId: CompletionEntryIdentifier | undefined, ): CompletionData | Request | undefined { const typeChecker = program.getTypeChecker(); @@ -1302,6 +1305,11 @@ namespace ts.Completions { const tokenTextLowerCase = tokenText.toLowerCase(); codefix.forEachExternalModuleToImportFrom(typeChecker, sourceFile, program.getSourceFiles(), moduleSymbol => { + // Perf -- ignore other modules if this is a request for details + if (detailsEntryId && detailsEntryId.source && stripQuotes(moduleSymbol.name) !== detailsEntryId.source) { + return; + } + for (let symbol of typeChecker.getExportsOfModule(moduleSymbol)) { // Don't add a completion for a re-export, only for the original. // The actual import fix might end up coming from a re-export -- we don't compute that until getting completion details. @@ -1320,7 +1328,7 @@ namespace ts.Completions { } const origin: SymbolOriginInfo = { type: "export", moduleSymbol, isDefaultExport }; - if (stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) { + if (detailsEntryId || stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) { symbols.push(symbol); symbolToOriginInfoMap[getSymbolId(symbol)] = origin; } diff --git a/tests/cases/fourslash/completionsImport_details_withMisspelledName.ts b/tests/cases/fourslash/completionsImport_details_withMisspelledName.ts new file mode 100644 index 00000000000..098f2e5d46e --- /dev/null +++ b/tests/cases/fourslash/completionsImport_details_withMisspelledName.ts @@ -0,0 +1,17 @@ +/// + +// @Filename: /a.ts +////export const abc = 0; + +// @Filename: /b.ts +////acb/**/; + +goTo.marker(""); +verify.applyCodeActionFromCompletion("", { + name: "abc", + source: "/a", + description: `Import 'abc' from module "./a"`, + newFileContent: `import { abc } from "./a"; + +acb;`, +}); From 222f35d9277de984eac9d13d85e7ef6d6cf675a9 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 23 Apr 2018 13:29:14 -0700 Subject: [PATCH 162/229] Make symbol display at ExportSpecifier use 'export', not 'import' (#23629) --- src/services/symbolDisplay.ts | 3 +++ tests/cases/fourslash/completionsImport_ofAlias.ts | 4 +--- .../cases/fourslash/findAllRefsForDefaultExport_reExport.ts | 6 +++--- ...orDefaultExport_reExport_allowSyntheticDefaultImports.ts | 6 +++--- tests/cases/fourslash/findAllRefsOnImportAliases.ts | 2 +- tests/cases/fourslash/findAllRefsOnImportAliases2.ts | 2 +- tests/cases/fourslash/findAllRefsReExportLocal.ts | 2 +- .../fourslash/findAllRefsReExportRightNameWrongSymbol.ts | 2 +- tests/cases/fourslash/findAllRefsReExport_broken.ts | 2 +- tests/cases/fourslash/findAllRefsReExport_broken2.ts | 2 +- tests/cases/fourslash/findAllRefsReExports.ts | 6 +++--- .../fourslash/quickInfoImportedTypesWithMergedMeanings.ts | 2 +- tests/cases/fourslash/renameImportOfExportEquals2.ts | 2 +- tests/cases/fourslash/renameImportOfReExport.ts | 2 +- tests/cases/fourslash/renameImportOfReExport2.ts | 2 +- tests/cases/fourslash/transitiveExportImports3.ts | 2 +- 16 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 7abb89befd7..854f5297d68 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -413,6 +413,9 @@ namespace ts.SymbolDisplay { displayParts.push(spacePart()); displayParts.push(keywordPart((symbol.declarations[0] as ExportAssignment).isExportEquals ? SyntaxKind.EqualsToken : SyntaxKind.DefaultKeyword)); break; + case SyntaxKind.ExportSpecifier: + displayParts.push(keywordPart(SyntaxKind.ExportKeyword)); + break; default: displayParts.push(keywordPart(SyntaxKind.ImportKeyword)); } diff --git a/tests/cases/fourslash/completionsImport_ofAlias.ts b/tests/cases/fourslash/completionsImport_ofAlias.ts index 903f724722e..e81f66ed2aa 100644 --- a/tests/cases/fourslash/completionsImport_ofAlias.ts +++ b/tests/cases/fourslash/completionsImport_ofAlias.ts @@ -21,9 +21,7 @@ goTo.marker(""); const options = { includeExternalModuleExports: true, sourceDisplay: "./a" }; -// TODO: https://github.com/Microsoft/TypeScript/issues/14003 -//TODO: verify that there's only one! -verify.completionListContains({ name: "foo", source: "/a" }, "(alias) const foo: 0\nimport foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, options); +verify.completionListContains({ name: "foo", source: "/a" }, "(alias) const foo: 0\nexport foo", "", "alias", /*spanIndex*/ undefined, /*hasAction*/ true, options); verify.not.completionListContains({ name: "foo", source: "/a_reexport" }, undefined, undefined, undefined, undefined, undefined, options); verify.not.completionListContains({ name: "foo", source: "/a_reexport_2" }, undefined, undefined, undefined, undefined, undefined, options); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts index 2154087d81a..2abd33b7d6e 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport.ts @@ -13,16 +13,16 @@ const [r0, r1, r2, r3] = test.ranges(); verify.referenceGroups([r0, r1], [ { definition: "const foo: 1", ranges: [r0, r1] }, - { definition: "(alias) const foo: 1\nimport default", ranges: [r2], }, + { definition: "(alias) const foo: 1\nexport default", ranges: [r2], }, { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, ]); verify.referenceGroups(r2, [ - { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, + { definition: "(alias) const foo: 1\nexport default", ranges: [r2] }, { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); verify.referenceGroups(r3, [ { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, - { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, + { definition: "(alias) const foo: 1\nexport default", ranges: [r2] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); diff --git a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.ts b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.ts index 41377a41aca..386eca5eae0 100644 --- a/tests/cases/fourslash/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.ts +++ b/tests/cases/fourslash/findAllRefsForDefaultExport_reExport_allowSyntheticDefaultImports.ts @@ -17,16 +17,16 @@ verify.noErrors(); const [r0, r1, r2, r3] = test.ranges(); verify.referenceGroups([r0, r1], [ { definition: "const foo: 1", ranges: [r0, r1] }, - { definition: "(alias) const foo: 1\nimport default", ranges: [r2], }, + { definition: "(alias) const foo: 1\nexport default", ranges: [r2], }, { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, ]); verify.referenceGroups(r2, [ - { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, + { definition: "(alias) const foo: 1\nexport default", ranges: [r2] }, { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); verify.referenceGroups(r3, [ { definition: "(alias) const fooDefault: 1\nimport fooDefault", ranges: [r3] }, - { definition: "(alias) const foo: 1\nimport default", ranges: [r2] }, + { definition: "(alias) const foo: 1\nexport default", ranges: [r2] }, { definition: "const foo: 1", ranges: [r0, r1] }, ]); diff --git a/tests/cases/fourslash/findAllRefsOnImportAliases.ts b/tests/cases/fourslash/findAllRefsOnImportAliases.ts index 6bec755bce3..17f947ffdc3 100644 --- a/tests/cases/fourslash/findAllRefsOnImportAliases.ts +++ b/tests/cases/fourslash/findAllRefsOnImportAliases.ts @@ -16,6 +16,6 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; const classes = { definition: "class Class", ranges: [r0] }; const imports = { definition: "(alias) class Class\nimport Class", ranges: [r1, r2] }; -const reExports = { definition: "(alias) class Class\nimport Class", ranges: [r3] }; +const reExports = { definition: "(alias) class Class\nexport Class", ranges: [r3] }; verify.referenceGroups(r0, [classes, imports, reExports]); verify.referenceGroups([r1, r2], [imports, classes, reExports]); diff --git a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts index 21dabf5b6e2..7be887c6af2 100644 --- a/tests/cases/fourslash/findAllRefsOnImportAliases2.ts +++ b/tests/cases/fourslash/findAllRefsOnImportAliases2.ts @@ -18,7 +18,7 @@ const [c2_0, c2_1] = c2Ranges; const c3Ranges = ranges.get("C3"); const classes = { definition: "class Class", ranges: classRanges }; const c2s = { definition: "(alias) class C2\nimport C2", ranges: c2Ranges }; -const c3s = { definition: "(alias) class C3\nimport C3", ranges: c3Ranges }; +const c3s = { definition: "(alias) class C3\nexport C3", ranges: c3Ranges }; verify.referenceGroups(classRanges, [classes, c2s, c3s]); diff --git a/tests/cases/fourslash/findAllRefsReExportLocal.ts b/tests/cases/fourslash/findAllRefsReExportLocal.ts index f57cc8480f0..ed1d0b105b6 100644 --- a/tests/cases/fourslash/findAllRefsReExportLocal.ts +++ b/tests/cases/fourslash/findAllRefsReExportLocal.ts @@ -19,7 +19,7 @@ const bxRanges = [bx0, bx1]; const byRanges = [by0, by1]; const axGroup = { definition: "var x: any", ranges: axRanges }; const bxGroup = { definition: "(alias) var x: any\nimport x", ranges: bxRanges }; -const ayGroup = { definition: "(alias) var y: any\nimport y", ranges: [ay] } +const ayGroup = { definition: "(alias) var y: any\nexport y", ranges: [ay] } const byGroup = { definition: "(alias) var y: any\nimport y", ranges: byRanges } verify.referenceGroups(axRanges, [axGroup, bxGroup, ayGroup, byGroup]); diff --git a/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts b/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts index 12305381fe8..8f4f61a90c3 100644 --- a/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts +++ b/tests/cases/fourslash/findAllRefsReExportRightNameWrongSymbol.ts @@ -24,7 +24,7 @@ const cFromAGroup = { definition: "(alias) const x: 0\nimport x", ranges: cFromA verify.referenceGroups(a, [aGroup, cFromAGroup]); const bGroup = { definition: "const x: 0", ranges: [b] }; -const cFromBGroup = { definition: "(alias) const x: 0\nimport x", ranges: [cFromB] }; +const cFromBGroup = { definition: "(alias) const x: 0\nexport x", ranges: [cFromB] }; const dGroup = { definition: "(alias) const x: 0\nimport x", ranges: [d] }; verify.referenceGroups(b, [bGroup, cFromBGroup, dGroup]); diff --git a/tests/cases/fourslash/findAllRefsReExport_broken.ts b/tests/cases/fourslash/findAllRefsReExport_broken.ts index 7c42d9e2b6c..92e4fcaa57c 100644 --- a/tests/cases/fourslash/findAllRefsReExport_broken.ts +++ b/tests/cases/fourslash/findAllRefsReExport_broken.ts @@ -3,4 +3,4 @@ // @Filename: /a.ts ////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] }; -verify.singleReferenceGroup("import x"); +verify.singleReferenceGroup("export x"); diff --git a/tests/cases/fourslash/findAllRefsReExport_broken2.ts b/tests/cases/fourslash/findAllRefsReExport_broken2.ts index 4f8a3ea5f45..1a6649465fb 100644 --- a/tests/cases/fourslash/findAllRefsReExport_broken2.ts +++ b/tests/cases/fourslash/findAllRefsReExport_broken2.ts @@ -3,4 +3,4 @@ // @Filename: /a.ts ////export { [|{| "isWriteAccess": true, "isDefinition": true |}x|] } from "nonsense"; -verify.singleReferenceGroup("import x"); +verify.singleReferenceGroup("export x"); diff --git a/tests/cases/fourslash/findAllRefsReExports.ts b/tests/cases/fourslash/findAllRefsReExports.ts index af2588de455..aafb13e3f5f 100644 --- a/tests/cases/fourslash/findAllRefsReExports.ts +++ b/tests/cases/fourslash/findAllRefsReExports.ts @@ -22,9 +22,9 @@ verify.noErrors(); const [foo0, foo1, bar0, foo2, defaultC, defaultD, bar1, baz0, defaultE, bang0, boom0, bar2, baz1, bang1, boom1] = test.ranges(); const a = { definition: "function foo(): void", ranges: [foo0, foo1, foo2] }; -const b = { definition: "(alias) function bar(): void\nimport bar", ranges: [bar0] }; -const c = { definition: "(alias) function foo(): void\nimport default", ranges: [defaultC, defaultE] }; -const d = { definition: "(alias) function foo(): void\nimport default", ranges: [defaultD] }; +const b = { definition: "(alias) function bar(): void\nexport bar", ranges: [bar0] }; +const c = { definition: "(alias) function foo(): void\nexport default", ranges: [defaultC, defaultE] }; +const d = { definition: "(alias) function foo(): void\nexport default", ranges: [defaultD] }; const eBar = { definition: "(alias) function bar(): void\nimport bar", ranges: [bar1, bar2] }; const eBaz = { definition: "(alias) function baz(): void\nimport baz", ranges: [baz0, baz1] }; const eBang = { definition: "(alias) function bang(): void\nimport bang", ranges: [bang0, bang1] }; diff --git a/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts b/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts index 8ffce0bbb28..d904fb59b9b 100644 --- a/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts +++ b/tests/cases/fourslash/quickInfoImportedTypesWithMergedMeanings.ts @@ -17,7 +17,7 @@ verify.quickInfoAt("1", [ "(alias) function Original(): void", "(alias) type Original = () => T", "(alias) namespace Original", - "import Original", + "export Original", ].join("\n"), "some docs "); verify.quickInfoAt("2", [ diff --git a/tests/cases/fourslash/renameImportOfExportEquals2.ts b/tests/cases/fourslash/renameImportOfExportEquals2.ts index 83ff1794bde..dfb472caab8 100644 --- a/tests/cases/fourslash/renameImportOfExportEquals2.ts +++ b/tests/cases/fourslash/renameImportOfExportEquals2.ts @@ -25,7 +25,7 @@ const qRanges = [Q0, Q1]; const ns = { definition: "namespace N", ranges: nRanges }; const os = { definition: "(alias) namespace O\nimport O", ranges: oRanges }; -const ps = { definition: "(alias) namespace P\nimport P", ranges: pRanges }; +const ps = { definition: "(alias) namespace P\nexport P", ranges: pRanges }; const qs = { definition: "(alias) namespace Q\nimport Q", ranges: qRanges }; verify.referenceGroups(nRanges, [ns, os, ps, qs]); diff --git a/tests/cases/fourslash/renameImportOfReExport.ts b/tests/cases/fourslash/renameImportOfReExport.ts index 6afb953ad53..2c684fde193 100644 --- a/tests/cases/fourslash/renameImportOfReExport.ts +++ b/tests/cases/fourslash/renameImportOfReExport.ts @@ -20,7 +20,7 @@ const ranges = test.ranges(); const [r0, r1, r2, r3] = ranges; const importRanges = [r2, r3]; const classes = { definition: "class C", ranges: [r0] }; -const bs = { definition: "(alias) class C\nimport C", ranges: [r1] }; +const bs = { definition: "(alias) class C\nexport C", ranges: [r1] }; const imports = { definition: "(alias) class C\nimport C", ranges: importRanges }; verify.referenceGroups(r0, [classes, bs, imports]); verify.referenceGroups(r1, [bs, imports, classes]); diff --git a/tests/cases/fourslash/renameImportOfReExport2.ts b/tests/cases/fourslash/renameImportOfReExport2.ts index bcaa0e41c8a..81b62249441 100644 --- a/tests/cases/fourslash/renameImportOfReExport2.ts +++ b/tests/cases/fourslash/renameImportOfReExport2.ts @@ -18,7 +18,7 @@ const cRanges = ranges.get("C"); const [d0, d1, d2] = ranges.get("D"); const classes = { definition: "class C", ranges: cRanges }; -const bImports = { definition: "(alias) class D\nimport D", ranges: [d0] }; +const bImports = { definition: "(alias) class D\nexport D", ranges: [d0] }; const cImports = { definition: "(alias) class D\nimport D", ranges: [d1, d2] }; verify.referenceGroups(cRanges, [classes, bImports, cImports]); diff --git a/tests/cases/fourslash/transitiveExportImports3.ts b/tests/cases/fourslash/transitiveExportImports3.ts index abb7b2a2983..aeac07476e4 100644 --- a/tests/cases/fourslash/transitiveExportImports3.ts +++ b/tests/cases/fourslash/transitiveExportImports3.ts @@ -13,7 +13,7 @@ verify.noErrors(); const [f0, f1, g0, f2, g1] = test.ranges(); const af = { definition: "function f(): void", ranges: [f0, f1] }; -const g0Group = { definition: "(alias) function g(): void\nimport g", ranges: [g0] }; +const g0Group = { definition: "(alias) function g(): void\nexport g", ranges: [g0] }; const g1Group = { definition: "(alias) function g(): void\nimport g", ranges: [g1] }; const bf = { definition: "(alias) function f(): void\nimport f", ranges: [f2] }; From 1f753b396217d9aabcdf9fbdadc0b49f852a8489 Mon Sep 17 00:00:00 2001 From: csigs Date: Mon, 23 Apr 2018 22:10:46 +0000 Subject: [PATCH 163/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 6 ++++ .../diagnosticMessages.generated.json.lcl | 28 ++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3715eb460a0..203d2c22ab9 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -915,6 +915,9 @@ + + + @@ -1017,6 +1020,9 @@ + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index c53a7b86387..092f291ac49 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -903,6 +903,15 @@ + + + + + + + + + @@ -999,24 +1008,9 @@ - + - - - - - - - - - - - - - - - - + From 905f9a02ad17da9e18c4cbeeee81eee7b1928ca7 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 23 Apr 2018 15:24:31 -0700 Subject: [PATCH 164/229] `module.exports = Entity` is an alias, just like `export = Entity` (#23570) * Make `module.export =` an alias like `export=` is This breaks a couple of tests for previous workarounds. Fix in upcoming commits. * Basically fixes all the breaks, but needs cleanup * More notes to myself * Clean up TODOs * Call mergeSymbolTable and delete export= afterward instead of basically copying the code myself. * More cleanup * Remove unnecessary check in import type checking * Revert to DIY code. It is more correct and will go away in a few days. * Exported class expressions can be used as type In both JS and TS * Do not require named class expressions --- src/compiler/binder.ts | 9 ++- src/compiler/checker.ts | 31 +++++++--- src/compiler/utilities.ts | 8 ++- .../commonJsImportClassExpression.js | 25 ++++++++ .../commonJsImportClassExpression.symbols | 19 ++++++ .../commonJsImportClassExpression.types | 22 +++++++ .../baselines/reference/es5ExportEquals.types | 2 +- .../baselines/reference/es6ExportEquals.types | 2 +- .../reference/jsdocImportType.symbols | 56 +++++++++++++++++ .../baselines/reference/jsdocImportType.types | 60 +++++++++++++++++++ .../reference/jsdocImportType2.symbols | 54 +++++++++++++++++ .../reference/jsdocImportType2.types | 59 ++++++++++++++++++ ...xportWithExportPropertyAssignment4.symbols | 16 ++--- .../compiler/commonJsImportClassExpression.ts | 9 +++ .../conformance/jsdoc/jsdocImportType.ts | 27 +++++++++ .../conformance/jsdoc/jsdocImportType2.ts | 26 ++++++++ .../fourslash/findAllRefsClassExpression0.ts | 2 +- .../fourslash/findAllRefsClassExpression1.ts | 2 +- 18 files changed, 402 insertions(+), 27 deletions(-) create mode 100644 tests/baselines/reference/commonJsImportClassExpression.js create mode 100644 tests/baselines/reference/commonJsImportClassExpression.symbols create mode 100644 tests/baselines/reference/commonJsImportClassExpression.types create mode 100644 tests/baselines/reference/jsdocImportType.symbols create mode 100644 tests/baselines/reference/jsdocImportType.types create mode 100644 tests/baselines/reference/jsdocImportType2.symbols create mode 100644 tests/baselines/reference/jsdocImportType2.types create mode 100644 tests/cases/compiler/commonJsImportClassExpression.ts create mode 100644 tests/cases/conformance/jsdoc/jsdocImportType.ts create mode 100644 tests/cases/conformance/jsdoc/jsdocImportType2.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index fe77e9b4df4..2557e3b7078 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -2220,14 +2220,14 @@ namespace ts { bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"` as __String); } - function bindExportAssignment(node: ExportAssignment | BinaryExpression) { + function bindExportAssignment(node: ExportAssignment) { if (!container.symbol || !container.symbol.exports) { // Export assignment in some sort of block construct bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node)); } else { const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) - // An export default clause with an EntityNameExpression exports all meanings of that identifier + // An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression; ? SymbolFlags.Alias // An export default clause with any other expression exports a value : SymbolFlags.Property; @@ -2322,7 +2322,10 @@ namespace ts { // 'module.exports = expr' assignment setCommonJsModuleIndicator(node); - declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule, SymbolFlags.None); + const flags = exportAssignmentIsAlias(node) + ? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class + : SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule; + declareSymbol(file.symbol.exports, file.symbol, node, flags, SymbolFlags.None); } function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76f9722342a..75f8715fca7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1926,13 +1926,17 @@ namespace ts { resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias); } - function getTargetOfExportAssignment(node: ExportAssignment, dontResolveAlias: boolean): Symbol | undefined { - const aliasLike = resolveEntityName(node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/ true, dontResolveAlias); + function getTargetOfExportAssignment(node: ExportAssignment | BinaryExpression, dontResolveAlias: boolean): Symbol | undefined { + const expression = (isExportAssignment(node) ? node.expression : node.right) as EntityNameExpression | ClassExpression; + if (isClassExpression(expression)) { + return checkExpression(expression).symbol; + } + const aliasLike = resolveEntityName(expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, /*ignoreErrors*/ true, dontResolveAlias); if (aliasLike) { return aliasLike; } - checkExpression(node.expression); - return getNodeLinks(node.expression).resolvedSymbol; + checkExpression(expression); + return getNodeLinks(expression).resolvedSymbol; } function getTargetOfAliasDeclaration(node: Declaration, dontRecursivelyResolve?: boolean): Symbol | undefined { @@ -1948,7 +1952,8 @@ namespace ts { case SyntaxKind.ExportSpecifier: return getTargetOfExportSpecifier(node, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace, dontRecursivelyResolve); case SyntaxKind.ExportAssignment: - return getTargetOfExportAssignment(node, dontRecursivelyResolve); + case SyntaxKind.BinaryExpression: + return getTargetOfExportAssignment((node), dontRecursivelyResolve); case SyntaxKind.NamespaceExportDeclaration: return getTargetOfNamespaceExportDeclaration(node, dontRecursivelyResolve); } @@ -2229,20 +2234,28 @@ namespace ts { // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, // and an external module with no 'export =' declaration resolves to the module itself. function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol { - return moduleSymbol && getMergedSymbol(resolveSymbol(getCommonJsExportEquals(moduleSymbol), dontResolveAlias)) || moduleSymbol; + return moduleSymbol && getMergedSymbol(getCommonJsExportEquals(resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.ExportEquals), dontResolveAlias), moduleSymbol)) || moduleSymbol; } - function getCommonJsExportEquals(moduleSymbol: Symbol): Symbol { - const exported = moduleSymbol.exports.get(InternalSymbolName.ExportEquals); - if (!exported || !exported.exports || moduleSymbol.exports.size === 1) { + function getCommonJsExportEquals(exported: Symbol, moduleSymbol: Symbol): Symbol { + if (!exported || moduleSymbol.exports.size === 1) { return exported; } const merged = cloneSymbol(exported); + if (merged.exports === undefined) { + merged.flags = merged.flags | SymbolFlags.ValueModule; + merged.exports = createSymbolTable(); + } moduleSymbol.exports.forEach((s, name) => { if (name === InternalSymbolName.ExportEquals) return; if (!merged.exports.has(name)) { merged.exports.set(name, s); } + else { + const ms = cloneSymbol(merged.exports.get(name)); + mergeSymbol(ms, s); + merged.exports.set(name, ms); + } }); return merged; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 5c94745f339..c5cb19e876a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2140,11 +2140,13 @@ namespace ts { node.kind === SyntaxKind.NamespaceImport || node.kind === SyntaxKind.ImportSpecifier || node.kind === SyntaxKind.ExportSpecifier || - node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node); + node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) || + isBinaryExpression(node) && getSpecialPropertyAssignmentKind(node) === SpecialPropertyAssignmentKind.ModuleExports; } - export function exportAssignmentIsAlias(node: ExportAssignment): boolean { - return isEntityNameExpression(node.expression); + export function exportAssignmentIsAlias(node: ExportAssignment | BinaryExpression): boolean { + const e = isExportAssignment(node) ? node.expression : node.right; + return isEntityNameExpression(e) || isClassExpression(e); } export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration) { diff --git a/tests/baselines/reference/commonJsImportClassExpression.js b/tests/baselines/reference/commonJsImportClassExpression.js new file mode 100644 index 00000000000..b460814b872 --- /dev/null +++ b/tests/baselines/reference/commonJsImportClassExpression.js @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/commonJsImportClassExpression.ts] //// + +//// [mod1.ts] +export = class { + chunk = 1 +} + +//// [use.ts] +import Chunk = require('./mod1') +declare var c: Chunk; +c.chunk; + + +//// [mod1.js] +"use strict"; +module.exports = /** @class */ (function () { + function class_1() { + this.chunk = 1; + } + return class_1; +}()); +//// [use.js] +"use strict"; +exports.__esModule = true; +c.chunk; diff --git a/tests/baselines/reference/commonJsImportClassExpression.symbols b/tests/baselines/reference/commonJsImportClassExpression.symbols new file mode 100644 index 00000000000..5f6bc93188f --- /dev/null +++ b/tests/baselines/reference/commonJsImportClassExpression.symbols @@ -0,0 +1,19 @@ +=== tests/cases/compiler/use.ts === +import Chunk = require('./mod1') +>Chunk : Symbol(Chunk, Decl(use.ts, 0, 0)) + +declare var c: Chunk; +>c : Symbol(c, Decl(use.ts, 1, 11)) +>Chunk : Symbol(Chunk, Decl(use.ts, 0, 0)) + +c.chunk; +>c.chunk : Symbol(Chunk.chunk, Decl(mod1.ts, 0, 16)) +>c : Symbol(c, Decl(use.ts, 1, 11)) +>chunk : Symbol(Chunk.chunk, Decl(mod1.ts, 0, 16)) + +=== tests/cases/compiler/mod1.ts === +export = class { + chunk = 1 +>chunk : Symbol((Anonymous class).chunk, Decl(mod1.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/commonJsImportClassExpression.types b/tests/baselines/reference/commonJsImportClassExpression.types new file mode 100644 index 00000000000..7bb32dea8e5 --- /dev/null +++ b/tests/baselines/reference/commonJsImportClassExpression.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/use.ts === +import Chunk = require('./mod1') +>Chunk : typeof Chunk + +declare var c: Chunk; +>c : Chunk +>Chunk : Chunk + +c.chunk; +>c.chunk : number +>c : Chunk +>chunk : number + +=== tests/cases/compiler/mod1.ts === +export = class { +>class { chunk = 1} : typeof (Anonymous class) + + chunk = 1 +>chunk : number +>1 : 1 +} + diff --git a/tests/baselines/reference/es5ExportEquals.types b/tests/baselines/reference/es5ExportEquals.types index 3397cf1df72..6c9e8930537 100644 --- a/tests/baselines/reference/es5ExportEquals.types +++ b/tests/baselines/reference/es5ExportEquals.types @@ -1,6 +1,6 @@ === tests/cases/compiler/es5ExportEquals.ts === export function f() { } ->f : () => void +>f : typeof f export = f; >f : () => void diff --git a/tests/baselines/reference/es6ExportEquals.types b/tests/baselines/reference/es6ExportEquals.types index 3503812aead..3ba761dc8e5 100644 --- a/tests/baselines/reference/es6ExportEquals.types +++ b/tests/baselines/reference/es6ExportEquals.types @@ -1,6 +1,6 @@ === tests/cases/compiler/es6ExportEquals.ts === export function f() { } ->f : () => void +>f : typeof f export = f; >f : () => void diff --git a/tests/baselines/reference/jsdocImportType.symbols b/tests/baselines/reference/jsdocImportType.symbols new file mode 100644 index 00000000000..657ad6801f1 --- /dev/null +++ b/tests/baselines/reference/jsdocImportType.symbols @@ -0,0 +1,56 @@ +=== tests/cases/conformance/jsdoc/use.js === +/// +/** @typedef {import("./mod1")} C + * @type {C} */ +var c; +>c : Symbol(c, Decl(use.js, 3, 3)) + +c.chunk; +>c.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>c : Symbol(c, Decl(use.js, 3, 3)) +>chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) + +const D = require("./mod1"); +>D : Symbol(D, Decl(use.js, 6, 5)) +>require : Symbol(require, Decl(types.d.ts, 0, 0)) +>"./mod1" : Symbol("tests/cases/conformance/jsdoc/mod1", Decl(mod1.js, 0, 0)) + +/** @type {D} */ +var d; +>d : Symbol(d, Decl(use.js, 8, 3)) + +d.chunk; +>d.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>d : Symbol(d, Decl(use.js, 8, 3)) +>chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) + +=== tests/cases/conformance/jsdoc/types.d.ts === +declare function require(name: string): any; +>require : Symbol(require, Decl(types.d.ts, 0, 0)) +>name : Symbol(name, Decl(types.d.ts, 0, 25)) + +declare var exports: any; +>exports : Symbol(exports, Decl(types.d.ts, 1, 11)) + +declare var module: { exports: any }; +>module : Symbol(module, Decl(types.d.ts, 2, 11)) +>exports : Symbol(exports, Decl(types.d.ts, 2, 21)) + +=== tests/cases/conformance/jsdoc/mod1.js === +/// +class Chunk { +>Chunk : Symbol(Chunk, Decl(mod1.js, 0, 0)) + + constructor() { + this.chunk = 1; +>this.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>this : Symbol(Chunk, Decl(mod1.js, 0, 0)) +>chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) + } +} +module.exports = Chunk; +>module.exports : Symbol(exports, Decl(types.d.ts, 2, 21)) +>module : Symbol(export=, Decl(mod1.js, 5, 1)) +>exports : Symbol(export=, Decl(mod1.js, 5, 1)) +>Chunk : Symbol(Chunk, Decl(mod1.js, 0, 0)) + diff --git a/tests/baselines/reference/jsdocImportType.types b/tests/baselines/reference/jsdocImportType.types new file mode 100644 index 00000000000..b2ac2764cd5 --- /dev/null +++ b/tests/baselines/reference/jsdocImportType.types @@ -0,0 +1,60 @@ +=== tests/cases/conformance/jsdoc/use.js === +/// +/** @typedef {import("./mod1")} C + * @type {C} */ +var c; +>c : Chunk + +c.chunk; +>c.chunk : number +>c : Chunk +>chunk : number + +const D = require("./mod1"); +>D : typeof Chunk +>require("./mod1") : typeof Chunk +>require : (name: string) => any +>"./mod1" : "./mod1" + +/** @type {D} */ +var d; +>d : Chunk + +d.chunk; +>d.chunk : number +>d : Chunk +>chunk : number + +=== tests/cases/conformance/jsdoc/types.d.ts === +declare function require(name: string): any; +>require : (name: string) => any +>name : string + +declare var exports: any; +>exports : any + +declare var module: { exports: any }; +>module : { exports: any; } +>exports : any + +=== tests/cases/conformance/jsdoc/mod1.js === +/// +class Chunk { +>Chunk : Chunk + + constructor() { + this.chunk = 1; +>this.chunk = 1 : 1 +>this.chunk : number +>this : this +>chunk : number +>1 : 1 + } +} +module.exports = Chunk; +>module.exports = Chunk : typeof Chunk +>module.exports : any +>module : { exports: any; } +>exports : any +>Chunk : typeof Chunk + diff --git a/tests/baselines/reference/jsdocImportType2.symbols b/tests/baselines/reference/jsdocImportType2.symbols new file mode 100644 index 00000000000..e67d250ca3d --- /dev/null +++ b/tests/baselines/reference/jsdocImportType2.symbols @@ -0,0 +1,54 @@ +=== tests/cases/conformance/jsdoc/use.js === +/// +/** @typedef {import("./mod1")} C + * @type {C} */ +var c; +>c : Symbol(c, Decl(use.js, 3, 3)) + +c.chunk; +>c.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>c : Symbol(c, Decl(use.js, 3, 3)) +>chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) + +const D = require("./mod1"); +>D : Symbol(D, Decl(use.js, 6, 5)) +>require : Symbol(require, Decl(types.d.ts, 0, 0)) +>"./mod1" : Symbol("tests/cases/conformance/jsdoc/mod1", Decl(mod1.js, 0, 0)) + +/** @type {D} */ +var d; +>d : Symbol(d, Decl(use.js, 8, 3)) + +d.chunk; +>d.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>d : Symbol(d, Decl(use.js, 8, 3)) +>chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) + +=== tests/cases/conformance/jsdoc/types.d.ts === +declare function require(name: string): any; +>require : Symbol(require, Decl(types.d.ts, 0, 0)) +>name : Symbol(name, Decl(types.d.ts, 0, 25)) + +declare var exports: any; +>exports : Symbol(exports, Decl(types.d.ts, 1, 11)) + +declare var module: { exports: any }; +>module : Symbol(module, Decl(types.d.ts, 2, 11)) +>exports : Symbol(exports, Decl(types.d.ts, 2, 21)) + +=== tests/cases/conformance/jsdoc/mod1.js === +/// +module.exports = class Chunk { +>module.exports : Symbol(exports, Decl(types.d.ts, 2, 21)) +>module : Symbol(export=, Decl(mod1.js, 0, 0)) +>exports : Symbol(export=, Decl(mod1.js, 0, 0)) +>Chunk : Symbol(Chunk, Decl(mod1.js, 1, 16)) + + constructor() { + this.chunk = 1; +>this.chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) +>this : Symbol(Chunk, Decl(mod1.js, 1, 16)) +>chunk : Symbol(Chunk.chunk, Decl(mod1.js, 2, 19)) + } +} + diff --git a/tests/baselines/reference/jsdocImportType2.types b/tests/baselines/reference/jsdocImportType2.types new file mode 100644 index 00000000000..c0dfb2d925a --- /dev/null +++ b/tests/baselines/reference/jsdocImportType2.types @@ -0,0 +1,59 @@ +=== tests/cases/conformance/jsdoc/use.js === +/// +/** @typedef {import("./mod1")} C + * @type {C} */ +var c; +>c : Chunk + +c.chunk; +>c.chunk : number +>c : Chunk +>chunk : number + +const D = require("./mod1"); +>D : typeof Chunk +>require("./mod1") : typeof Chunk +>require : (name: string) => any +>"./mod1" : "./mod1" + +/** @type {D} */ +var d; +>d : Chunk + +d.chunk; +>d.chunk : number +>d : Chunk +>chunk : number + +=== tests/cases/conformance/jsdoc/types.d.ts === +declare function require(name: string): any; +>require : (name: string) => any +>name : string + +declare var exports: any; +>exports : any + +declare var module: { exports: any }; +>module : { exports: any; } +>exports : any + +=== tests/cases/conformance/jsdoc/mod1.js === +/// +module.exports = class Chunk { +>module.exports = class Chunk { constructor() { this.chunk = 1; }} : typeof Chunk +>module.exports : any +>module : { exports: any; } +>exports : any +>class Chunk { constructor() { this.chunk = 1; }} : typeof Chunk +>Chunk : typeof Chunk + + constructor() { + this.chunk = 1; +>this.chunk = 1 : 1 +>this.chunk : number +>this : this +>chunk : number +>1 : 1 + } +} + diff --git a/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols b/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols index b62a68c83f3..e7cbcfa0828 100644 --- a/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols +++ b/tests/baselines/reference/moduleExportWithExportPropertyAssignment4.symbols @@ -13,14 +13,14 @@ mod1.justExport.toFixed() >toFixed : Symbol(Number.toFixed, Decl(lib.d.ts, --, --)) mod1.bothBefore.toFixed() // error ->mod1.bothBefore : Symbol(bothBefore) +>mod1.bothBefore : Symbol(A.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) ->bothBefore : Symbol(bothBefore) +>bothBefore : Symbol(A.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) mod1.bothAfter.toFixed() ->mod1.bothAfter : Symbol(bothAfter) +>mod1.bothAfter : Symbol(A.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) >mod1 : Symbol(mod1, Decl(a.js, 1, 3)) ->bothAfter : Symbol(bothAfter) +>bothAfter : Symbol(A.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) mod1.justProperty.length >mod1.justProperty.length : Symbol(String.length, Decl(lib.d.ts, --, --)) @@ -41,10 +41,10 @@ declare function require(name: string): any; === tests/cases/conformance/salsa/mod1.js === /// module.exports.bothBefore = 'string' ->module.exports : Symbol(bothBefore, Decl(mod1.js, 0, 0)) +>module.exports : Symbol(A.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) >module : Symbol(module, Decl(requires.d.ts, 0, 11)) >exports : Symbol(exports, Decl(requires.d.ts, 0, 21)) ->bothBefore : Symbol(bothBefore, Decl(mod1.js, 0, 0)) +>bothBefore : Symbol(A.bothBefore, Decl(mod1.js, 2, 16), Decl(mod1.js, 0, 0)) A.justExport = 4 >A.justExport : Symbol(A.justExport, Decl(mod1.js, 1, 36)) @@ -74,10 +74,10 @@ function A() { >p : Symbol(A.p, Decl(mod1.js, 6, 14)) } module.exports.bothAfter = 'string' ->module.exports : Symbol(bothAfter, Decl(mod1.js, 8, 1)) +>module.exports : Symbol(A.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) >module : Symbol(module, Decl(requires.d.ts, 0, 11)) >exports : Symbol(exports, Decl(requires.d.ts, 0, 21)) ->bothAfter : Symbol(bothAfter, Decl(mod1.js, 8, 1)) +>bothAfter : Symbol(A.bothAfter, Decl(mod1.js, 3, 16), Decl(mod1.js, 8, 1)) module.exports.justProperty = 'string' >module.exports : Symbol(justProperty, Decl(mod1.js, 9, 35)) diff --git a/tests/cases/compiler/commonJsImportClassExpression.ts b/tests/cases/compiler/commonJsImportClassExpression.ts new file mode 100644 index 00000000000..1cd856d4b1b --- /dev/null +++ b/tests/cases/compiler/commonJsImportClassExpression.ts @@ -0,0 +1,9 @@ +// @Filename: mod1.ts +export = class { + chunk = 1 +} + +// @Filename: use.ts +import Chunk = require('./mod1') +declare var c: Chunk; +c.chunk; diff --git a/tests/cases/conformance/jsdoc/jsdocImportType.ts b/tests/cases/conformance/jsdoc/jsdocImportType.ts new file mode 100644 index 00000000000..7b960601dc7 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocImportType.ts @@ -0,0 +1,27 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: types.d.ts +declare function require(name: string): any; +declare var exports: any; +declare var module: { exports: any }; +// @Filename: mod1.js +/// +class Chunk { + constructor() { + this.chunk = 1; + } +} +module.exports = Chunk; + +// @Filename: use.js +/// +/** @typedef {import("./mod1")} C + * @type {C} */ +var c; +c.chunk; + +const D = require("./mod1"); +/** @type {D} */ +var d; +d.chunk; diff --git a/tests/cases/conformance/jsdoc/jsdocImportType2.ts b/tests/cases/conformance/jsdoc/jsdocImportType2.ts new file mode 100644 index 00000000000..98ffc506144 --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocImportType2.ts @@ -0,0 +1,26 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: types.d.ts +declare function require(name: string): any; +declare var exports: any; +declare var module: { exports: any }; +// @Filename: mod1.js +/// +module.exports = class Chunk { + constructor() { + this.chunk = 1; + } +} + +// @Filename: use.js +/// +/** @typedef {import("./mod1")} C + * @type {C} */ +var c; +c.chunk; + +const D = require("./mod1"); +/** @type {D} */ +var d; +d.chunk; diff --git a/tests/cases/fourslash/findAllRefsClassExpression0.ts b/tests/cases/fourslash/findAllRefsClassExpression0.ts index 50abfae0230..e8d4aa671a3 100644 --- a/tests/cases/fourslash/findAllRefsClassExpression0.ts +++ b/tests/cases/fourslash/findAllRefsClassExpression0.ts @@ -11,6 +11,6 @@ const [r0, r1, r2, r3] = test.ranges(); const defs = { definition: "(local class) A", ranges: [r0, r1] }; -const imports = { definition: 'import A = require("./a")', ranges: [r2, r3] }; +const imports = { definition: '(alias) (local class) A\nimport A = require("./a")', ranges: [r2, r3] }; verify.referenceGroups([r0, r1], [defs, imports]); verify.referenceGroups([r2, r3], [imports, defs]); diff --git a/tests/cases/fourslash/findAllRefsClassExpression1.ts b/tests/cases/fourslash/findAllRefsClassExpression1.ts index bd581871842..64aad512a5e 100644 --- a/tests/cases/fourslash/findAllRefsClassExpression1.ts +++ b/tests/cases/fourslash/findAllRefsClassExpression1.ts @@ -11,7 +11,7 @@ const [r0, r1, r2] = test.ranges(); const defs = { definition: "(local class) A", ranges: [r0] }; -const imports = { definition: 'import A = require("./a")', ranges: [r1, r2] }; +const imports = { definition: '(alias) (local class) A\nimport A = require("./a")', ranges: [r1, r2] }; verify.referenceGroups([r0], [defs, imports]); verify.referenceGroups([r1, r2], [imports, defs]); From 6ec763884ec9a2bd2ea8c0a1465fc5bbcc13ccd7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 23 Apr 2018 14:57:10 -0700 Subject: [PATCH 165/229] Fix the crash when reporting errors of file that was referenced by inferred project root, is opened right after closing the root file Fixes the crash reported in https://github.com/Microsoft/TypeScript/issues/23255#issuecomment-382653325 --- .../unittests/tsserverProjectSystem.ts | 93 ++++++++++++++++++- src/server/editorServices.ts | 19 ++-- .../reference/api/tsserverlibrary.d.ts | 1 - 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index a35f797eaa1..1c0dd0beb5c 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -480,6 +480,10 @@ namespace ts.projectSystem { checkNthEvent(session, server.toEvent(eventName, diagnostics), 0, isMostRecent); } + function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: ReadonlyArray = [], category = diagnosticCategoryName(message), reportsUnnecessary?: {}): protocol.Diagnostic { + return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category, reportsUnnecessary, source: undefined }; + } + function checkCompleteEvent(session: TestSession, numberOfCurrentEvents: number, expectedSequenceId: number, isMostRecent = true): void { checkNthEvent(session, server.toEvent("requestCompleted", { request_seq: expectedSequenceId }), numberOfCurrentEvents - 1, isMostRecent); } @@ -496,7 +500,7 @@ namespace ts.projectSystem { function checkNthEvent(session: TestSession, expectedEvent: protocol.Event, index: number, isMostRecent: boolean) { const events = session.events; - assert.deepEqual(events[index], expectedEvent); + assert.deepEqual(events[index], expectedEvent, `Expected ${JSON.stringify(expectedEvent)} at ${index} in ${JSON.stringify(events)}`); const outputs = session.host.getOutput(); assert.equal(outputs[index], server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, session.host.newLine)); @@ -3333,6 +3337,89 @@ namespace ts.projectSystem { checkCompleteEvent(session, 1, expectedSequenceId); session.clearMessages(); }); + + it("Reports errors correctly when file referenced by inferred project root, is opened right after closing the root file", () => { + const projectRoot = "/user/username/projects/myproject"; + const app: FileOrFolder = { + path: `${projectRoot}/src/client/app.js`, + content: "" + }; + const serverUtilities: FileOrFolder = { + path: `${projectRoot}/src/server/utilities.js`, + content: `function getHostName() { return "hello"; } export { getHostName };` + }; + const backendTest: FileOrFolder = { + path: `${projectRoot}/test/backend/index.js`, + content: `import { getHostName } from '../../src/server/utilities';export default getHostName;` + }; + const files = [libFile, app, serverUtilities, backendTest]; + const host = createServerHost(files); + const session = createSession(host, { useInferredProjectPerProjectRoot: true, canUseEvents: true }); + session.executeCommandSeq({ + command: protocol.CommandTypes.Open, + arguments: { + file: app.path, + projectRootPath: projectRoot + } + }); + const service = session.getProjectService(); + checkNumberOfProjects(service, { inferredProjects: 1 }); + const project = service.inferredProjects[0]; + checkProjectActualFiles(project, [libFile.path, app.path]); + session.executeCommandSeq({ + command: protocol.CommandTypes.Open, + arguments: { + file: backendTest.path, + projectRootPath: projectRoot + } + }); + checkNumberOfProjects(service, { inferredProjects: 1 }); + checkProjectActualFiles(project, files.map(f => f.path)); + checkErrors([backendTest.path, app.path]); + session.executeCommandSeq({ + command: protocol.CommandTypes.Close, + arguments: { + file: backendTest.path + } + }); + session.executeCommandSeq({ + command: protocol.CommandTypes.Open, + arguments: { + file: serverUtilities.path, + projectRootPath: projectRoot + } + }); + checkErrors([serverUtilities.path, app.path]); + + function checkErrors(openFiles: [string, string]) { + const expectedSequenceId = session.getNextSeq(); + session.executeCommandSeq({ + command: protocol.CommandTypes.Geterr, + arguments: { + delay: 0, + files: openFiles + } + }); + + for (const openFile of openFiles) { + session.clearMessages(); + host.checkTimeoutQueueLength(3); + host.runQueuedTimeoutCallbacks(host.getNextTimeoutId() - 1); + + checkErrorMessage(session, "syntaxDiag", { file: openFile, diagnostics: [] }); + session.clearMessages(); + + host.runQueuedImmediateCallbacks(); + checkErrorMessage(session, "semanticDiag", { file: openFile, diagnostics: [] }); + session.clearMessages(); + + host.runQueuedImmediateCallbacks(1); + checkErrorMessage(session, "suggestionDiag", { file: openFile, diagnostics: [] }); + } + checkCompleteEvent(session, 2, expectedSequenceId); + session.clearMessages(); + } + }); }); describe("tsserverProjectSystem autoDiscovery", () => { @@ -4293,10 +4380,6 @@ namespace ts.projectSystem { session.clearMessages(); }); - - function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: ReadonlyArray = [], category = diagnosticCategoryName(message), reportsUnnecessary?: {}): protocol.Diagnostic { - return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category, reportsUnnecessary, source: undefined }; - } }); describe("tsserverProjectSystem Configure file diagnostics events", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 1271b98c1c7..dfd5539cca3 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -310,6 +310,10 @@ namespace ts.server { return `Project: ${project ? project.getProjectName() : ""} WatchType: ${watchType}`; } + function updateProjectIfDirty(project: Project) { + return project.dirty && project.updateGraph(); + } + export class ProjectService { /*@internal*/ @@ -673,7 +677,7 @@ namespace ts.server { let hasChanges = this.pendingEnsureProjectForOpenFiles; this.pendingProjectUpdates.clear(); const updateGraph = (project: Project) => { - hasChanges = this.updateProjectIfDirty(project) || hasChanges; + hasChanges = updateProjectIfDirty(project) || hasChanges; }; this.externalProjects.forEach(updateGraph); @@ -684,10 +688,6 @@ namespace ts.server { } } - private updateProjectIfDirty(project: Project) { - return project.dirty && project.updateGraph(); - } - getFormatCodeOptions(file: NormalizedPath) { const info = this.getScriptInfoForNormalizedPath(file); return info && info.getFormatCodeSettings() || this.hostConfiguration.formatCodeOptions; @@ -1980,7 +1980,7 @@ namespace ts.server { } }); this.pendingEnsureProjectForOpenFiles = false; - this.inferredProjects.forEach(p => this.updateProjectIfDirty(p)); + this.inferredProjects.forEach(updateProjectIfDirty); this.logger.info("Structure after ensureProjectForOpenFiles:"); this.printProjects(); @@ -2027,7 +2027,7 @@ namespace ts.server { } else { // Ensure project is ready to check if it contains opened script info - project.updateGraph(); + updateProjectIfDirty(project); } } } @@ -2036,6 +2036,11 @@ namespace ts.server { // - external project search, which updates the project before checking if info is present in it // - configured project - either created or updated to ensure we know correct status of info + // At this point we need to ensure that containing projects of the info are uptodate + // This will ensure that later question of info.isOrphan() will return correct answer + // and we correctly create inferred project for the info + info.containingProjects.forEach(updateProjectIfDirty); + // At this point if file is part of any any configured or external project, then it would be present in the containing projects // So if it still doesnt have any containing projects, it needs to be part of inferred project if (info.isOrphan()) { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 9bd2de6aa41..1f5757ff4ce 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8050,7 +8050,6 @@ declare namespace ts.server { * ensure that each open script info has project */ private ensureProjectStructuresUptoDate; - private updateProjectIfDirty; getFormatCodeOptions(file: NormalizedPath): FormatCodeSettings; getPreferences(file: NormalizedPath): UserPreferences; private onSourceFileChanged; From fc30bd10e33ee513c7e99978c9193b179f670f30 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 23 Apr 2018 16:05:37 -0700 Subject: [PATCH 166/229] Suggestion to convert to ES6 module should only trigger in projects which express some intent to use ES6 (#23576) --- src/services/completions.ts | 7 ++----- src/services/suggestionDiagnostics.ts | 2 +- src/services/utilities.ts | 7 +++++++ .../refactorConvertToEs6Module_export_alias.ts | 1 + ...refactorConvertToEs6Module_export_dotDefault.ts | 1 + ...efactorConvertToEs6Module_export_invalidName.ts | 1 + ...orConvertToEs6Module_export_moduleDotExports.ts | 1 + ...6Module_export_moduleDotExportsEqualsRequire.ts | 1 + ...odule_export_moduleDotExports_changesImports.ts | 1 + .../refactorConvertToEs6Module_export_named.ts | 1 + ...nvertToEs6Module_export_namedClassExpression.ts | 1 + ...rtToEs6Module_export_namedFunctionExpression.ts | 1 + .../refactorConvertToEs6Module_export_object.ts | 1 + ...orConvertToEs6Module_export_object_shorthand.ts | 1 + ...refactorConvertToEs6Module_export_referenced.ts | 3 +-- ...orConvertToEs6Module_expressionToDeclaration.ts | 1 + ...onvertToEs6Module_import_arrayBindingPattern.ts | 1 + ...ConvertToEs6Module_import_includeDefaultUses.ts | 1 + ...ToEs6Module_import_multipleUniqueIdentifiers.ts | 1 + ...s6Module_import_multipleVariableDeclarations.ts | 1 + ...rtToEs6Module_import_nameFromModuleSpecifier.ts | 1 + ...s6Module_import_objectBindingPattern_complex.ts | 1 + ...oEs6Module_import_objectBindingPattern_plain.ts | 1 + ...orConvertToEs6Module_import_onlyNamedImports.ts | 1 + ...ctorConvertToEs6Module_import_propertyAccess.ts | 1 + .../refactorConvertToEs6Module_import_shadowing.ts | 1 + ...refactorConvertToEs6Module_import_sideEffect.ts | 1 + ...efactorConvertToEs6Module_missingInitializer.ts | 1 + ...actorConvertToEs6Module_notInCommonjsProject.ts | 10 ++++++++++ ...dule_notInCommonjsProject_yesIfSomeEs6Module.ts | 14 ++++++++++++++ .../refactorConvertToEs6Module_preserveQuotes.ts | 2 ++ 31 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject.ts create mode 100644 tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject_yesIfSomeEs6Module.ts diff --git a/src/services/completions.ts b/src/services/completions.ts index f57f108812c..236823992fc 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1201,14 +1201,11 @@ namespace ts.Completions { // If already using commonjs, don't introduce ES6. if (sourceFile.commonJsModuleIndicator) return false; // If some file is using ES6 modules, assume that it's OK to add more. - if (program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator)) { - return true; - } + if (programContainsEs6Modules(program)) return true; // For JS, stay on the safe side. if (isSourceFileJavaScript(sourceFile)) return false; // If module transpilation is enabled or we're targeting es6 or above, or not emitting, OK. - const compilerOptions = program.getCompilerOptions(); - return !!compilerOptions.module || compilerOptions.target >= ScriptTarget.ES2015 || !!compilerOptions.noEmit; + return compilerOptionsIndicateEs6Modules(program.getCompilerOptions()); } function isSnippetScope(scopeNode: Node): boolean { diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index d9f55a78d82..d04f3f15cf9 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -5,7 +5,7 @@ namespace ts { const checker = program.getDiagnosticsProducingTypeChecker(); const diags: Diagnostic[] = []; - if (sourceFile.commonJsModuleIndicator) { + if (sourceFile.commonJsModuleIndicator && (programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions()))) { diags.push(createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module)); } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index cd87824e7d6..78f18869b37 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1214,6 +1214,13 @@ namespace ts { : getTextOfIdentifierOrLiteral(name); } + export function programContainsEs6Modules(program: Program): boolean { + return program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator); + } + export function compilerOptionsIndicateEs6Modules(compilerOptions: CompilerOptions): boolean { + return !!compilerOptions.module || compilerOptions.target >= ScriptTarget.ES2015 || !!compilerOptions.noEmit; + } + export function hostUsesCaseSensitiveFileNames(host: LanguageServiceHost): boolean { return host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false; } diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts index 8749488b88e..56fe9d0808c 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_alias.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const exportsAlias = exports; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts index 1283b0053a8..8bd74041dec 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_dotDefault.ts @@ -3,6 +3,7 @@ // Test that we leave it alone if the name is a keyword. // @allowJs: true +// @target: esnext // @Filename: /a.js ////exports.default = 0; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts index 83a831effb0..bec40f756ad 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_invalidName.ts @@ -3,6 +3,7 @@ // Test that we leave it alone if the name is a keyword. // @allowJs: true +// @target: esnext // @Filename: /a.js ////exports.class = 0; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts index 3382228babb..327f7b480a9 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////module.exports = function() {} diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts index 81877c8a98b..8dd77f06e1d 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExportsEqualsRequire.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.d.ts ////export const x: number; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts index 84f081d24b3..277525e10fe 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_moduleDotExports_changesImports.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////module.exports = 0; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts index a748b9844a6..e7ee2908580 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_named.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////[|exports.f|] = function() {}; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts index ff14f00867d..e1cb86e8d68 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedClassExpression.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////exports.C = class E { static instance = new E(); } diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts index 94a14d1a4c3..c4468a1a189 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_namedFunctionExpression.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////exports.f = function g() { g(); } diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts index 61c46c98b3c..5b9107f275c 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////module.exports = { diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts index f6fe1048820..62588f6a531 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_object_shorthand.ts @@ -3,6 +3,7 @@ // TODO: Maybe we could transform this to `export function f() {}`. // @allowJs: true +// @target: esnext // @Filename: /a.js ////function f() {} diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts index 0811ea13e99..7a5b94b0a98 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_export_referenced.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////exports.x = 0; @@ -15,8 +16,6 @@ //// exports.z; z; ////} -// TODO: GH#22492 Should be a able access `exports.z` inside `exports.f` - verify.codeFix({ description: "Convert to ES6 module", newFileContent: diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts index e22aa176738..47ff26f459e 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////exports.f = async function* f(p) { p; } diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts index 2c53f48a6eb..f373f00dfe7 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_arrayBindingPattern.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const [x, y] = /*a*/require/*b*/("x"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts index 0e69f9519ee..a75854595f3 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_includeDefaultUses.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const x = /*a*/require/*b*/("x"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts index 44750b76e6e..faf8ec5eb69 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleUniqueIdentifiers.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const x = require("x"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts index ae387c060c7..33f31299f8b 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_multipleVariableDeclarations.ts @@ -3,6 +3,7 @@ // Test that we leave it alone if the name is a keyword. // @allowJs: true +// @target: esnext // @Filename: /a.js ////const x = require("x"), y = 0, { z } = require("z"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts index 510b610315a..3427e62fb9c 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_nameFromModuleSpecifier.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const [] = require("a-b"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts index f1397e46207..74071ba55fb 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_complex.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const { x: { a, b } } = require("x"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts index 52cb72783b1..31b9cb41f62 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_objectBindingPattern_plain.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const { x, y: z } = require("x"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts index 7f66b67685e..2b40e1ade36 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_onlyNamedImports.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const x = require("x"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts index 8d299d4f0ec..dea48380597 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_propertyAccess.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const x = require("x").default; diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts index dec87859901..f506f970085 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_shadowing.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////const mod = require("mod"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts index 28caeaf2411..e8023ac414a 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts @@ -3,6 +3,7 @@ // Test that we leave it alone if the name is a keyword. // @allowJs: true +// @target: esnext // @Filename: /a.js ////require("foo"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts b/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts index 77c4ce0fc43..90a256c2480 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_missingInitializer.ts @@ -1,6 +1,7 @@ /// // @allowJs: true +// @target: esnext // @Filename: /a.js ////require("m"); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject.ts b/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject.ts new file mode 100644 index 00000000000..5286091bce9 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject.ts @@ -0,0 +1,10 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////exports.x = 0; + +// No suggestion to convert to an ES6 module, +// since there are no es6 modules in this project and we don't have a high enough target. +verify.getSuggestionDiagnostics([]); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject_yesIfSomeEs6Module.ts b/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject_yesIfSomeEs6Module.ts new file mode 100644 index 00000000000..491b61a0bc2 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToEs6Module_notInCommonjsProject_yesIfSomeEs6Module.ts @@ -0,0 +1,14 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////exports.x = 0; + +// @Filename: /b.js +////export const y = 0; + +verify.codeFix({ + description: "Convert to ES6 module", + newFileContent: "export const x = 0;", +}); diff --git a/tests/cases/fourslash/refactorConvertToEs6Module_preserveQuotes.ts b/tests/cases/fourslash/refactorConvertToEs6Module_preserveQuotes.ts index 8aa81538887..d8c48d0e971 100644 --- a/tests/cases/fourslash/refactorConvertToEs6Module_preserveQuotes.ts +++ b/tests/cases/fourslash/refactorConvertToEs6Module_preserveQuotes.ts @@ -1,6 +1,8 @@ /// // @allowJs: true +// @target: esnext + // @Filename: /a.js ////const a = require('a'); a; From 09590bc041c261ba0ccb3d9321fb2499765ec8b6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Apr 2018 20:57:11 -0700 Subject: [PATCH 167/229] Transform 'keyof (A | B)' to 'keyof A & keyof B' --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75f8715fca7..b94d14d58a5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8268,7 +8268,8 @@ namespace ts { } function getIndexType(type: Type, stringsOnly = keyofStringsOnly): Type { - return type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly))) : + return type.flags & TypeFlags.Union ? getIntersectionType(map((type).types, t => getIndexType(t, stringsOnly))) : + type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly))) : maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : type === wildcardType ? wildcardType : From 2911d5d7d75d98329192328a24d360c14719e6a7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Apr 2018 20:57:20 -0700 Subject: [PATCH 168/229] Accept new baselines --- .../reference/keyofAndIndexedAccess.types | 20 +++++++------- .../keyofAndIndexedAccessErrors.errors.txt | 24 +++++++++++------ .../keyofAndIndexedAccessErrors.types | 26 +++++++++---------- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 4e41b58e664..1df9dd4e42b 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -890,11 +890,11 @@ function f60(source: T, target: T) { } function f70(func: (k1: keyof (T | U), k2: keyof (T & U)) => void) { ->f70 : (func: (k1: keyof (T | U), k2: keyof T | keyof U) => void) => void ->func : (k1: keyof (T | U), k2: keyof T | keyof U) => void +>f70 : (func: (k1: keyof T & keyof U, k2: keyof T | keyof U) => void) => void +>func : (k1: keyof T & keyof U, k2: keyof T | keyof U) => void >T : T >U : U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U >T : T >U : U >k2 : keyof T | keyof U @@ -903,7 +903,7 @@ function f70(func: (k1: keyof (T | U), k2: keyof (T & U)) => void) { func<{ a: any, b: any }, { a: any, c: any }>('a', 'a'); >func<{ a: any, b: any }, { a: any, c: any }>('a', 'a') : void ->func : (k1: keyof (T | U), k2: keyof T | keyof U) => void +>func : (k1: keyof T & keyof U, k2: keyof T | keyof U) => void >a : any >b : any >a : any @@ -913,7 +913,7 @@ function f70(func: (k1: keyof (T | U), k2: keyof (T & U)) => void) { func<{ a: any, b: any }, { a: any, c: any }>('a', 'b'); >func<{ a: any, b: any }, { a: any, c: any }>('a', 'b') : void ->func : (k1: keyof (T | U), k2: keyof T | keyof U) => void +>func : (k1: keyof T & keyof U, k2: keyof T | keyof U) => void >a : any >b : any >a : any @@ -923,7 +923,7 @@ function f70(func: (k1: keyof (T | U), k2: keyof (T & U)) => void) { func<{ a: any, b: any }, { a: any, c: any }>('a', 'c'); >func<{ a: any, b: any }, { a: any, c: any }>('a', 'c') : void ->func : (k1: keyof (T | U), k2: keyof T | keyof U) => void +>func : (k1: keyof T & keyof U, k2: keyof T | keyof U) => void >a : any >b : any >a : any @@ -1097,8 +1097,8 @@ function f73(func: (x: T, y: U, k: K) => (T & U)[ } function f74(func: (x: T, y: U, k: K) => (T | U)[K]) { ->f74 : (func: (x: T, y: U, k: K) => (T | U)[K]) => void ->func : (x: T, y: U, k: K) => (T | U)[K] +>f74 : (func: (x: T, y: U, k: K) => (T | U)[K]) => void +>func : (x: T, y: U, k: K) => (T | U)[K] >T : T >U : U >K : K @@ -1117,7 +1117,7 @@ function f74(func: (x: T, y: U, k: K) => (T | U)[ let a = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a'); // number >a : number >func({ a: 1, b: "hello" }, { a: 2, b: true }, 'a') : number ->func : (x: T, y: U, k: K) => (T | U)[K] +>func : (x: T, y: U, k: K) => (T | U)[K] >{ a: 1, b: "hello" } : { a: number; b: string; } >a : number >1 : 1 @@ -1133,7 +1133,7 @@ function f74(func: (x: T, y: U, k: K) => (T | U)[ let b = func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b'); // string | boolean >b : string | boolean >func({ a: 1, b: "hello" }, { a: 2, b: true }, 'b') : string | boolean ->func : (x: T, y: U, k: K) => (T | U)[K] +>func : (x: T, y: U, k: K) => (T | U)[K] >{ a: 1, b: "hello" } : { a: number; b: string; } >a : number >1 : 1 diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index f9bb63c43b1..37af61dd943 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -26,10 +26,14 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(72,5): error tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error TS2322: Type 'T | U' is not assignable to type 'T & U'. Type 'T' is not assignable to type 'T & U'. Type 'T' is not assignable to type 'U'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof (T | U)'. - Type 'keyof T' is not assignable to type 'keyof (T | U)'. - Type 'string | number | symbol' is not assignable to type 'keyof (T | U)'. - Type 'string' is not assignable to type 'keyof (T | U)'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof T & keyof U'. + Type 'string | number | symbol' is not assignable to type 'keyof T & keyof U'. + Type 'string' is not assignable to type 'keyof T & keyof U'. + Type 'string' is not assignable to type 'keyof T'. + Type 'keyof T' is not assignable to type 'keyof U'. + Type 'string | number | symbol' is not assignable to type 'keyof U'. + Type 'string' is not assignable to type 'keyof U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,9): error TS2322: Type 'Extract' is not assignable to type 'K'. Type 'string & keyof T' is not assignable to type 'K'. Type 'string' is not assignable to type 'K'. @@ -179,10 +183,14 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error !!! error TS2322: Type 'T' is not assignable to type 'U'. k1 = k2; // Error ~~ -!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof (T | U)'. -!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof (T | U)'. -!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof (T | U)'. -!!! error TS2322: Type 'string' is not assignable to type 'keyof (T | U)'. +!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof T'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'. +!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof U'. +!!! error TS2322: Type 'string' is not assignable to type 'keyof U'. k2 = k1; } diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 2f50ef5c53c..6f79f6cf64a 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -34,19 +34,19 @@ type T02 = keyof keyof Object; >Object : Object type T03 = keyof keyof keyof Object; ->T03 : "toString" | "toLocaleString" | "valueOf" +>T03 : "toString" | "valueOf" | ("toString" & number) | ("toLocaleString" & number) | ("valueOf" & number) | ("toFixed" & number) | ("toExponential" & number) | ("toPrecision" & number) >Object : Object type T04 = keyof keyof keyof keyof Object; ->T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | ("toString" & number) | ("valueOf" & number) | (number & "length") | (number & "toString") | (number & "toLocaleString") | (number & "valueOf") | (number & "charAt") | (number & "charCodeAt") | (number & "concat") | (number & "indexOf") | (number & "lastIndexOf") | (number & "localeCompare") | (number & "match") | (number & "replace") | (number & "search") | (number & "slice") | (number & "split") | (number & "substring") | (number & "toLowerCase") | (number & "toLocaleLowerCase") | (number & "toUpperCase") | (number & "toLocaleUpperCase") | (number & "trim") | (number & "substr") | (number & "toFixed") | (number & "toExponential") | (number & "toPrecision") | ("length" & number) | ("charAt" & number) | ("charCodeAt" & number) | ("concat" & number) | ("indexOf" & number) | ("lastIndexOf" & number) | ("localeCompare" & number) | ("match" & number) | ("replace" & number) | ("search" & number) | ("slice" & number) | ("split" & number) | ("substring" & number) | ("toLowerCase" & number) | ("toLocaleLowerCase" & number) | ("toUpperCase" & number) | ("toLocaleUpperCase" & number) | ("trim" & number) | ("substr" & number) >Object : Object type T05 = keyof keyof keyof keyof keyof Object; ->T05 : "toString" | "toLocaleString" | "valueOf" +>T05 : "toString" | "valueOf" | ("toString" & number) | ("toLocaleString" & number) | ("valueOf" & number) | ("toFixed" & number) | ("toExponential" & number) | ("toPrecision" & number) >Object : Object type T06 = keyof keyof keyof keyof keyof keyof Object; ->T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" +>T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | ("toString" & number) | ("valueOf" & number) | (number & "length") | (number & "toString") | (number & "toLocaleString") | (number & "valueOf") | (number & "charAt") | (number & "charCodeAt") | (number & "concat") | (number & "indexOf") | (number & "lastIndexOf") | (number & "localeCompare") | (number & "match") | (number & "replace") | (number & "search") | (number & "slice") | (number & "split") | (number & "substring") | (number & "toLowerCase") | (number & "toLocaleLowerCase") | (number & "toUpperCase") | (number & "toLocaleUpperCase") | (number & "trim") | (number & "substr") | (number & "toFixed") | (number & "toExponential") | (number & "toPrecision") | ("length" & number) | ("charAt" & number) | ("charCodeAt" & number) | ("concat" & number) | ("indexOf" & number) | ("lastIndexOf" & number) | ("localeCompare" & number) | ("match" & number) | ("replace" & number) | ("search" & number) | ("slice" & number) | ("split" & number) | ("substring" & number) | ("toLowerCase" & number) | ("toLocaleLowerCase" & number) | ("toUpperCase" & number) | ("toLocaleUpperCase" & number) | ("trim" & number) | ("substr" & number) >Object : Object type T10 = Shape["name"]; @@ -243,10 +243,10 @@ function f10(shape: Shape) { } function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { ->f20 : (k1: keyof (T | U), k2: keyof T | keyof U, o1: T | U, o2: T & U) => void +>f20 : (k1: keyof T & keyof U, k2: keyof T | keyof U, o1: T | U, o2: T & U) => void >T : T >U : U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U >T : T >U : U >k2 : keyof T | keyof U @@ -260,9 +260,9 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >U : U o1[k1]; ->o1[k1] : (T | U)[keyof (T | U)] +>o1[k1] : (T | U)[keyof T & keyof U] >o1 : T | U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U o1[k2]; // Error >o1[k2] : (T | U)[keyof T | keyof U] @@ -270,9 +270,9 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >k2 : keyof T | keyof U o2[k1]; ->o2[k1] : (T & U)[keyof (T | U)] +>o2[k1] : (T & U)[keyof T & keyof U] >o2 : T & U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U o2[k2]; >o2[k2] : (T & U)[keyof T | keyof U] @@ -291,13 +291,13 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { k1 = k2; // Error >k1 = k2 : keyof T | keyof U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U >k2 : keyof T | keyof U k2 = k1; ->k2 = k1 : keyof (T | U) +>k2 = k1 : keyof T & keyof U >k2 : keyof T | keyof U ->k1 : keyof (T | U) +>k1 : keyof T & keyof U } // Repro from #17166 From 7befd35009742d47c1f5e7a37d88c2b721745a2c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Apr 2018 21:09:49 -0700 Subject: [PATCH 169/229] Add tests --- .../types/keyof/keyofAndIndexedAccess.ts | 18 ++++++++++ .../keyof/keyofAndIndexedAccessErrors.ts | 33 ++++++++++++++----- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index e0c1f544d97..03d4ae01ea1 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -567,3 +567,21 @@ function f3>(t: T, k: K, tk: T[K]): void { type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] } + +// Repro from #23618 + +type DBBoolTable = { [k in K]: 0 | 1 } +enum Flag { + FLAG_1 = "flag_1", + FLAG_2 = "flag_2" +} + +type SimpleDBRecord = { staticField: number } & DBBoolTable +function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { + return record[flags[0]]; +} + +type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable +function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { + return record[flags[0]]; +} diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts index 618f483655e..bb2b9d95117 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts @@ -67,15 +67,32 @@ function f10(shape: Shape) { setProperty(shape, cond ? "name" : "size", 10); // Error } -function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { - o1[k1]; - o1[k2]; // Error - o2[k1]; - o2[k2]; - o1 = o2; - o2 = o1; // Error - k1 = k2; // Error +function f20(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) { + x[k1]; + x[k2]; + x[k3]; // Error + x[k4]; // Error + + y[k1]; + y[k2]; + y[k3]; + y[k4]; + + k1 = k2; + k1 = k3; // Error + k1 = k4; // Error + k2 = k1; + k2 = k3; // Error + k2 = k4; // Error + + k3 = k1; + k3 = k2; + k3 = k4; + + k4 = k1; + k4 = k2; + k4 = k3; } // Repro from #17166 From f0c3291976c3d1fd389ab37c6cb5433a2b72494f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Apr 2018 21:09:56 -0700 Subject: [PATCH 170/229] Accept new baselines --- .../reference/keyofAndIndexedAccess.js | 46 ++++ .../reference/keyofAndIndexedAccess.symbols | 61 +++++ .../reference/keyofAndIndexedAccess.types | 69 ++++++ .../keyofAndIndexedAccessErrors.errors.txt | 84 +++++-- .../reference/keyofAndIndexedAccessErrors.js | 61 +++-- .../keyofAndIndexedAccessErrors.symbols | 222 +++++++++++------- .../keyofAndIndexedAccessErrors.types | 128 +++++++--- 7 files changed, 515 insertions(+), 156 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 422cef5a574..f0af336563c 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -565,6 +565,24 @@ function f3>(t: T, k: K, tk: T[K]): void { type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] } + +// Repro from #23618 + +type DBBoolTable = { [k in K]: 0 | 1 } +enum Flag { + FLAG_1 = "flag_1", + FLAG_2 = "flag_2" +} + +type SimpleDBRecord = { staticField: number } & DBBoolTable +function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { + return record[flags[0]]; +} + +type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable +function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { + return record[flags[0]]; +} //// [keyofAndIndexedAccess.js] @@ -948,6 +966,17 @@ function f3(t, k, tk) { t[key] = tk; // ok, T[K] ==> T[keyof T] } } +var Flag; +(function (Flag) { + Flag["FLAG_1"] = "flag_1"; + Flag["FLAG_2"] = "flag_2"; +})(Flag || (Flag = {})); +function getFlagsFromSimpleRecord(record, flags) { + return record[flags[0]]; +} +function getFlagsFromDynamicRecord(record, flags) { + return record[flags[0]]; +} //// [keyofAndIndexedAccess.d.ts] @@ -1212,3 +1241,20 @@ declare function f3>(t: T, k: K, tk: T[K]) declare type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]; }; +declare type DBBoolTable = { + [k in K]: 0 | 1; +}; +declare enum Flag { + FLAG_1 = "flag_1", + FLAG_2 = "flag_2" +} +declare type SimpleDBRecord = { + staticField: number; +} & DBBoolTable; +declare function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]): SimpleDBRecord[Flag]; +declare type DynamicDBRecord = ({ + dynamicField: number; +} | { + dynamicField: string; +}) & DBBoolTable; +declare function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]): DynamicDBRecord[Flag]; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index b1206a49388..27c7128e42d 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -2010,3 +2010,64 @@ type Predicates = { >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3)) } +// Repro from #23618 + +type DBBoolTable = { [k in K]: 0 | 1 } +>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 17)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 569, 40)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 17)) + +enum Flag { +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 569, 56)) + + FLAG_1 = "flag_1", +>FLAG_1 : Symbol(Flag.FLAG_1, Decl(keyofAndIndexedAccess.ts, 570, 11)) + + FLAG_2 = "flag_2" +>FLAG_2 : Symbol(Flag.FLAG_2, Decl(keyofAndIndexedAccess.ts, 571, 22)) +} + +type SimpleDBRecord = { staticField: number } & DBBoolTable +>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 573, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 575, 20)) +>staticField : Symbol(staticField, Decl(keyofAndIndexedAccess.ts, 575, 44)) +>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 575, 20)) + +function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { +>getFlagsFromSimpleRecord : Symbol(getFlagsFromSimpleRecord, Decl(keyofAndIndexedAccess.ts, 575, 86)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34)) +>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 576, 55)) +>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 573, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34)) +>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 576, 84)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 576, 34)) + + return record[flags[0]]; +>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 576, 55)) +>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 576, 84)) +} + +type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable +>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 578, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 580, 21)) +>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 580, 46)) +>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 580, 73)) +>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 565, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 580, 21)) + +function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { +>getFlagsFromDynamicRecord : Symbol(getFlagsFromDynamicRecord, Decl(keyofAndIndexedAccess.ts, 580, 117)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35)) +>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 581, 56)) +>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 578, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35)) +>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 581, 86)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 581, 35)) + + return record[flags[0]]; +>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 581, 56)) +>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 581, 86)) +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 1df9dd4e42b..de35c620d33 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -2345,3 +2345,72 @@ type Predicates = { >T : T } +// Repro from #23618 + +type DBBoolTable = { [k in K]: 0 | 1 } +>DBBoolTable : DBBoolTable +>K : K +>k : k +>K : K + +enum Flag { +>Flag : Flag + + FLAG_1 = "flag_1", +>FLAG_1 : Flag.FLAG_1 +>"flag_1" : "flag_1" + + FLAG_2 = "flag_2" +>FLAG_2 : Flag.FLAG_2 +>"flag_2" : "flag_2" +} + +type SimpleDBRecord = { staticField: number } & DBBoolTable +>SimpleDBRecord : SimpleDBRecord +>Flag : Flag +>staticField : number +>DBBoolTable : DBBoolTable +>Flag : Flag + +function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { +>getFlagsFromSimpleRecord : (record: SimpleDBRecord, flags: Flag[]) => SimpleDBRecord[Flag] +>Flag : Flag +>record : SimpleDBRecord +>SimpleDBRecord : SimpleDBRecord +>Flag : Flag +>flags : Flag[] +>Flag : Flag + + return record[flags[0]]; +>record[flags[0]] : SimpleDBRecord[Flag] +>record : SimpleDBRecord +>flags[0] : Flag +>flags : Flag[] +>0 : 0 +} + +type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable +>DynamicDBRecord : DynamicDBRecord +>Flag : Flag +>dynamicField : number +>dynamicField : string +>DBBoolTable : DBBoolTable +>Flag : Flag + +function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { +>getFlagsFromDynamicRecord : (record: DynamicDBRecord, flags: Flag[]) => DynamicDBRecord[Flag] +>Flag : Flag +>record : DynamicDBRecord +>DynamicDBRecord : DynamicDBRecord +>Flag : Flag +>flags : Flag[] +>Flag : Flag + + return record[flags[0]]; +>record[flags[0]] : DynamicDBRecord[Flag] +>record : DynamicDBRecord +>flags[0] : Flag +>flags : Flag[] +>0 : 0 +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 37af61dd943..bbd4685a492 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -22,11 +22,9 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(64,33): error tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(66,24): error TS2345: Argument of type '"size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(67,24): error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type '"name" | "width" | "height" | "visible"'. Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(72,5): error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error TS2322: Type 'T | U' is not assignable to type 'T & U'. - Type 'T' is not assignable to type 'T & U'. - Type 'T' is not assignable to type 'U'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(73,5): error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(74,5): error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(82,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. Type 'keyof T' is not assignable to type 'keyof T & keyof U'. Type 'string | number | symbol' is not assignable to type 'keyof T & keyof U'. Type 'string' is not assignable to type 'keyof T & keyof U'. @@ -34,25 +32,34 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error Type 'keyof T' is not assignable to type 'keyof U'. Type 'string | number | symbol' is not assignable to type 'keyof U'. Type 'string' is not assignable to type 'keyof U'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,9): error TS2322: Type 'Extract' is not assignable to type 'K'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(83,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof U'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof U'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(87,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof T & keyof U'. + Type 'keyof T' is not assignable to type 'keyof U'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(103,9): error TS2322: Type 'Extract' is not assignable to type 'K'. Type 'string & keyof T' is not assignable to type 'K'. Type 'string' is not assignable to type 'K'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(88,9): error TS2322: Type 'T[Extract]' is not assignable to type 'T[K]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(105,9): error TS2322: Type 'T[Extract]' is not assignable to type 'T[K]'. Type 'Extract' is not assignable to type 'K'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(91,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(108,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. Type 'T' is not assignable to type 'U'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(94,5): error TS2322: Type 'T[J]' is not assignable to type 'U[J]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(111,5): error TS2322: Type 'T[J]' is not assignable to type 'U[J]'. Type 'T' is not assignable to type 'U'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(97,5): error TS2322: Type 'T[K]' is not assignable to type 'T[J]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(114,5): error TS2322: Type 'T[K]' is not assignable to type 'T[J]'. Type 'K' is not assignable to type 'J'. Type 'Extract' is not assignable to type 'J'. Type 'string & keyof T' is not assignable to type 'J'. Type 'string' is not assignable to type 'J'. -tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'. Type 'T' is not assignable to type 'U'. -==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (31 errors) ==== +==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (34 errors) ==== class Shape { name: string; width: number; @@ -168,20 +175,23 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error !!! error TS2345: Type '"size"' is not assignable to type '"name" | "width" | "height" | "visible"'. } - function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { - o1[k1]; - o1[k2]; // Error - ~~~~~~ + function f20(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) { + x[k1]; + x[k2]; + x[k3]; // Error + ~~~~~ !!! error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'. - o2[k1]; - o2[k2]; - o1 = o2; - o2 = o1; // Error - ~~ -!!! error TS2322: Type 'T | U' is not assignable to type 'T & U'. -!!! error TS2322: Type 'T' is not assignable to type 'T & U'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. - k1 = k2; // Error + x[k4]; // Error + ~~~~~ +!!! error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'. + + y[k1]; + y[k2]; + y[k3]; + y[k4]; + + k1 = k2; + k1 = k3; // Error ~~ !!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. !!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'. @@ -191,7 +201,31 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error !!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'. !!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof U'. !!! error TS2322: Type 'string' is not assignable to type 'keyof U'. + k1 = k4; // Error + ~~ +!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'. + k2 = k1; + k2 = k3; // Error + ~~ +!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'. + k2 = k4; // Error + ~~ +!!! error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof T & keyof U'. +!!! error TS2322: Type 'keyof T' is not assignable to type 'keyof U'. + + k3 = k1; + k3 = k2; + k3 = k4; + + k4 = k1; + k4 = k2; + k4 = k3; } // Repro from #17166 diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.js b/tests/baselines/reference/keyofAndIndexedAccessErrors.js index 0f026d5d2e5..c64f4df5331 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.js +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.js @@ -68,15 +68,32 @@ function f10(shape: Shape) { setProperty(shape, cond ? "name" : "size", 10); // Error } -function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { - o1[k1]; - o1[k2]; // Error - o2[k1]; - o2[k2]; - o1 = o2; - o2 = o1; // Error - k1 = k2; // Error +function f20(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) { + x[k1]; + x[k2]; + x[k3]; // Error + x[k4]; // Error + + y[k1]; + y[k2]; + y[k3]; + y[k4]; + + k1 = k2; + k1 = k3; // Error + k1 = k4; // Error + k2 = k1; + k2 = k3; // Error + k2 = k4; // Error + + k3 = k1; + k3 = k2; + k3 = k4; + + k4 = k1; + k4 = k2; + k4 = k3; } // Repro from #17166 @@ -122,15 +139,27 @@ function f10(shape) { setProperty(shape, "size", 10); // Error setProperty(shape, cond ? "name" : "size", 10); // Error } -function f20(k1, k2, o1, o2) { - o1[k1]; - o1[k2]; // Error - o2[k1]; - o2[k2]; - o1 = o2; - o2 = o1; // Error - k1 = k2; // Error +function f20(x, y, k1, k2, k3, k4) { + x[k1]; + x[k2]; + x[k3]; // Error + x[k4]; // Error + y[k1]; + y[k2]; + y[k3]; + y[k4]; + k1 = k2; + k1 = k3; // Error + k1 = k4; // Error k2 = k1; + k2 = k3; // Error + k2 = k4; // Error + k3 = k1; + k3 = k2; + k3 = k4; + k4 = k1; + k4 = k2; + k4 = k3; } // Repro from #17166 function f3(t, k, tk, u, j, uk, tj, uj) { diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols index d062677fa02..bb86bf68bee 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols @@ -219,142 +219,196 @@ function f10(shape: Shape) { >cond : Symbol(cond, Decl(keyofAndIndexedAccessErrors.ts, 50, 11)) } -function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { +function f20(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) { >f20 : Symbol(f20, Decl(keyofAndIndexedAccessErrors.ts, 67, 1)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13)) >U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15)) ->k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) +>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13)) >U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15)) ->k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37)) +>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13)) >U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15)) ->o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13)) >U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15)) ->o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15)) +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) >T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 69, 13)) >U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 69, 15)) - o1[k1]; ->o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56)) ->k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) + x[k1]; +>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) - o1[k2]; // Error ->o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56)) ->k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37)) + x[k2]; +>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) - o2[k1]; ->o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67)) ->k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) + x[k3]; // Error +>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) - o2[k2]; ->o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67)) ->k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37)) + x[k4]; // Error +>x : Symbol(x, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) - o1 = o2; ->o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56)) ->o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67)) + y[k1]; +>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) - o2 = o1; // Error ->o2 : Symbol(o2, Decl(keyofAndIndexedAccessErrors.ts, 69, 67)) ->o1 : Symbol(o1, Decl(keyofAndIndexedAccessErrors.ts, 69, 56)) + y[k2]; +>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) - k1 = k2; // Error ->k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) ->k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37)) + y[k3]; +>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) + + y[k4]; +>y : Symbol(y, Decl(keyofAndIndexedAccessErrors.ts, 69, 28)) +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) + + k1 = k2; +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) + + k1 = k3; // Error +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) + + k1 = k4; // Error +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) k2 = k1; ->k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37)) ->k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) + + k2 = k3; // Error +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) + + k2 = k4; // Error +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) + + k3 = k1; +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) + + k3 = k2; +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) + + k3 = k4; +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) + + k4 = k1; +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 38)) + + k4 = k2; +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 57)) + + k4 = k3; +>k4 : Symbol(k4, Decl(keyofAndIndexedAccessErrors.ts, 69, 99)) +>k3 : Symbol(k3, Decl(keyofAndIndexedAccessErrors.ts, 69, 80)) } // Repro from #17166 function f3, U extends T, J extends K>( ->f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 78, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 95, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14)) >Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50)) ->T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63)) ->K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 98, 50)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12)) +>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 98, 63)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14)) t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void { ->t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77)) ->T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9)) ->K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) ->T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) ->u : Symbol(u, Decl(keyofAndIndexedAccessErrors.ts, 82, 25)) ->U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50)) ->j : Symbol(j, Decl(keyofAndIndexedAccessErrors.ts, 82, 31)) ->J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63)) ->uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37)) ->U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50)) ->K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) ->tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47)) ->T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) ->J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63)) ->uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57)) ->U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 50)) ->J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 63)) +>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 98, 77)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 99, 9)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14)) +>u : Symbol(u, Decl(keyofAndIndexedAccessErrors.ts, 99, 25)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 98, 50)) +>j : Symbol(j, Decl(keyofAndIndexedAccessErrors.ts, 99, 31)) +>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 98, 63)) +>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 99, 37)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 98, 50)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 98, 14)) +>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 98, 12)) +>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 98, 63)) +>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57)) +>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 98, 50)) +>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 98, 63)) for (let key in t) { ->key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) ->t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12)) +>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 98, 77)) key = k // ok, K ==> keyof T ->key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) ->k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 99, 9)) k = key // error, keyof T =/=> K ->k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9)) ->key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 99, 9)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12)) t[key] = tk; // ok, T[K] ==> T[keyof T] ->t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77)) ->key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) +>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 98, 77)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) tk = t[key]; // error, T[keyof T] =/=> T[K] ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) ->t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 77)) ->key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) +>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 98, 77)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 100, 12)) } tk = uk; ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) ->uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) +>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 99, 37)) uk = tk; // error ->uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) +>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 99, 37)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) tj = uj; ->tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47)) ->uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57)) +>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47)) +>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57)) uj = tj; // error ->uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57)) ->tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47)) +>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57)) +>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47)) tk = tj; ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) ->tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) +>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47)) tj = tk; // error ->tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) +>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 99, 47)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) tk = uj; ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) ->uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) +>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57)) uj = tk; // error ->uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15)) +>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 99, 57)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 99, 15)) } diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 6f79f6cf64a..6a474c18107 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -242,62 +242,128 @@ function f10(shape: Shape) { >10 : 10 } -function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { ->f20 : (k1: keyof T & keyof U, k2: keyof T | keyof U, o1: T | U, o2: T & U) => void +function f20(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) { +>f20 : (x: T | U, y: T & U, k1: keyof T & keyof U, k2: keyof T & keyof U, k3: keyof T | keyof U, k4: keyof T | keyof U) => void +>T : T +>U : U +>x : T | U +>T : T +>U : U +>y : T & U >T : T >U : U >k1 : keyof T & keyof U >T : T >U : U ->k2 : keyof T | keyof U +>k2 : keyof T & keyof U >T : T >U : U ->o1 : T | U +>k3 : keyof T | keyof U >T : T >U : U ->o2 : T & U +>k4 : keyof T | keyof U >T : T >U : U - o1[k1]; ->o1[k1] : (T | U)[keyof T & keyof U] ->o1 : T | U + x[k1]; +>x[k1] : (T | U)[keyof T & keyof U] +>x : T | U >k1 : keyof T & keyof U - o1[k2]; // Error ->o1[k2] : (T | U)[keyof T | keyof U] ->o1 : T | U ->k2 : keyof T | keyof U + x[k2]; +>x[k2] : (T | U)[keyof T & keyof U] +>x : T | U +>k2 : keyof T & keyof U - o2[k1]; ->o2[k1] : (T & U)[keyof T & keyof U] ->o2 : T & U + x[k3]; // Error +>x[k3] : (T | U)[keyof T | keyof U] +>x : T | U +>k3 : keyof T | keyof U + + x[k4]; // Error +>x[k4] : (T | U)[keyof T | keyof U] +>x : T | U +>k4 : keyof T | keyof U + + y[k1]; +>y[k1] : (T & U)[keyof T & keyof U] +>y : T & U >k1 : keyof T & keyof U - o2[k2]; ->o2[k2] : (T & U)[keyof T | keyof U] ->o2 : T & U ->k2 : keyof T | keyof U + y[k2]; +>y[k2] : (T & U)[keyof T & keyof U] +>y : T & U +>k2 : keyof T & keyof U - o1 = o2; ->o1 = o2 : T & U ->o1 : T | U ->o2 : T & U + y[k3]; +>y[k3] : (T & U)[keyof T | keyof U] +>y : T & U +>k3 : keyof T | keyof U - o2 = o1; // Error ->o2 = o1 : T | U ->o2 : T & U ->o1 : T | U + y[k4]; +>y[k4] : (T & U)[keyof T | keyof U] +>y : T & U +>k4 : keyof T | keyof U - k1 = k2; // Error ->k1 = k2 : keyof T | keyof U + k1 = k2; +>k1 = k2 : keyof T & keyof U >k1 : keyof T & keyof U ->k2 : keyof T | keyof U +>k2 : keyof T & keyof U + + k1 = k3; // Error +>k1 = k3 : keyof T | keyof U +>k1 : keyof T & keyof U +>k3 : keyof T | keyof U + + k1 = k4; // Error +>k1 = k4 : keyof T | keyof U +>k1 : keyof T & keyof U +>k4 : keyof T | keyof U k2 = k1; >k2 = k1 : keyof T & keyof U ->k2 : keyof T | keyof U +>k2 : keyof T & keyof U >k1 : keyof T & keyof U + + k2 = k3; // Error +>k2 = k3 : keyof T | keyof U +>k2 : keyof T & keyof U +>k3 : keyof T | keyof U + + k2 = k4; // Error +>k2 = k4 : keyof T | keyof U +>k2 : keyof T & keyof U +>k4 : keyof T | keyof U + + k3 = k1; +>k3 = k1 : keyof T & keyof U +>k3 : keyof T | keyof U +>k1 : keyof T & keyof U + + k3 = k2; +>k3 = k2 : keyof T & keyof U +>k3 : keyof T | keyof U +>k2 : keyof T & keyof U + + k3 = k4; +>k3 = k4 : keyof T | keyof U +>k3 : keyof T | keyof U +>k4 : keyof T | keyof U + + k4 = k1; +>k4 = k1 : keyof T & keyof U +>k4 : keyof T | keyof U +>k1 : keyof T & keyof U + + k4 = k2; +>k4 = k2 : keyof T & keyof U +>k4 : keyof T | keyof U +>k2 : keyof T & keyof U + + k4 = k3; +>k4 = k3 : keyof T | keyof U +>k4 : keyof T | keyof U +>k3 : keyof T | keyof U } // Repro from #17166 From 90500e88df32f17dc3e09ec776a4195b0e614173 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 24 Apr 2018 04:10:22 +0000 Subject: [PATCH 171/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages/diagnosticMessages.generated.json.lcl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 092f291ac49..619c6ea41af 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1011,6 +1011,9 @@ + + + From 0e5ea2c8f6236113d792ed3d022b3adfbd4af4c6 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 24 Apr 2018 10:10:45 +0000 Subject: [PATCH 172/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 33 ++++++++++--------- .../diagnosticMessages.generated.json.lcl | 12 +++++++ 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index b6189dcec82..546572f66c2 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -903,6 +903,15 @@ + + + + + + + + + @@ -999,27 +1008,15 @@ - + - + - + - - - - - - - - - - - - @@ -6507,6 +6504,12 @@ + + + + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index d4801255fdb..7c615261dea 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -906,6 +906,9 @@ + + + @@ -1008,6 +1011,9 @@ + + + @@ -6498,6 +6504,12 @@ + + + + + + From eca17ac2434f94979960dfa30bad99ef62ab03db Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 24 Apr 2018 08:54:14 -0700 Subject: [PATCH 173/229] Support import fix even when the error is that a type is used as a value (#23655) --- src/services/codefixes/importFixes.ts | 3 ++- .../fourslash/importNameCodeFix_typeUsedAsValue.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/importNameCodeFix_typeUsedAsValue.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 5a10f2f48a7..26fa45d1e53 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -7,7 +7,8 @@ namespace ts.codefix { Diagnostics.Cannot_find_name_0.code, Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, Diagnostics.Cannot_find_namespace_0.code, - Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code + Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code, + Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here.code, ], getCodeActions: getImportCodeActions, // TODO: GH#20315 diff --git a/tests/cases/fourslash/importNameCodeFix_typeUsedAsValue.ts b/tests/cases/fourslash/importNameCodeFix_typeUsedAsValue.ts new file mode 100644 index 00000000000..ec0fa115d0b --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_typeUsedAsValue.ts @@ -0,0 +1,14 @@ +/// + +// @Filename: /a.ts +////export class ReadonlyArray {} + +// @Filename: /b.ts +////[|new ReadonlyArray();|] + +goTo.file("/b.ts"); +verify.importFixAtPosition([ +`import { ReadonlyArray } from "./a"; + +new ReadonlyArray();`, +]); From 969aa45ea539cb2e9ab217bf1606a297c0e71190 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 24 Apr 2018 08:54:42 -0700 Subject: [PATCH 174/229] Improve error message for unused type (#23633) --- src/compiler/checker.ts | 3 ++- src/compiler/diagnosticMessages.json | 5 +++++ src/services/codefixes/fixUnusedIdentifier.ts | 1 + .../noUnusedLocals_selfReference.errors.txt | 16 +++++++-------- .../unusedClassesinModule1.errors.txt | 4 ++-- .../unusedClassesinNamespace1.errors.txt | 4 ++-- .../unusedClassesinNamespace2.errors.txt | 4 ++-- .../unusedClassesinNamespace4.errors.txt | 4 ++-- .../unusedClassesinNamespace5.errors.txt | 4 ++-- .../unusedIdentifiersConsolidated1.errors.txt | 20 +++++++++---------- .../unusedInterfaceinNamespace1.errors.txt | 4 ++-- .../unusedInterfaceinNamespace2.errors.txt | 4 ++-- .../unusedInterfaceinNamespace3.errors.txt | 4 ++-- .../unusedLocalsAndParameters.errors.txt | 4 ++-- ...LocalsAndParametersTypeAliases2.errors.txt | 8 ++++---- 15 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75f8715fca7..da2d83e4d18 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -22183,7 +22183,8 @@ namespace ts { } if (!isRemovedPropertyFromObjectSpread(node.kind === SyntaxKind.Identifier ? node.parent : node)) { - addDiagnostic(UnusedKind.Local, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, Diagnostics._0_is_declared_but_its_value_is_never_read, name)); + const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read; + addDiagnostic(UnusedKind.Local, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, message, name)); } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2bb6d4bec61..2c376da7bc9 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3530,6 +3530,11 @@ "category": "Message", "code": 6195 }, + "'{0}' is declared but never used.": { + "category": "Error", + "code": 6196, + "reportsUnnecessary": true + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index a37435cd109..fd360c73ea1 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -5,6 +5,7 @@ namespace ts.codefix { const fixIdDelete = "unusedIdentifier_delete"; const errorCodes = [ Diagnostics._0_is_declared_but_its_value_is_never_read.code, + Diagnostics._0_is_declared_but_never_used.code, Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code, Diagnostics.All_imports_in_import_declaration_are_unused.code, ]; diff --git a/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt b/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt index 4202a580f84..ff2291c84d6 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt +++ b/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt @@ -1,9 +1,9 @@ tests/cases/compiler/noUnusedLocals_selfReference.ts(3,1): error TS6133: 'f' is declared but its value is never read. tests/cases/compiler/noUnusedLocals_selfReference.ts(5,5): error TS6133: 'g' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(9,1): error TS6133: 'C' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(12,1): error TS6133: 'E' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(13,1): error TS6133: 'I' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(14,1): error TS6133: 'T' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference.ts(9,1): error TS6196: 'C' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(12,1): error TS6196: 'E' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(13,1): error TS6196: 'I' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(14,1): error TS6196: 'T' is declared but never used. tests/cases/compiler/noUnusedLocals_selfReference.ts(15,1): error TS6133: 'N' is declared but its value is never read. tests/cases/compiler/noUnusedLocals_selfReference.ts(22,19): error TS6133: 'm' is declared but its value is never read. @@ -23,18 +23,18 @@ tests/cases/compiler/noUnusedLocals_selfReference.ts(22,19): error TS6133: 'm' i } class C { ~~~~~~~ -!!! error TS6133: 'C' is declared but its value is never read. +!!! error TS6196: 'C' is declared but never used. m() { C; } } enum E { A = 0, B = E.A } ~~~~~~ -!!! error TS6133: 'E' is declared but its value is never read. +!!! error TS6196: 'E' is declared but never used. interface I { x: I }; ~~~~~~~~~~~ -!!! error TS6133: 'I' is declared but its value is never read. +!!! error TS6196: 'I' is declared but never used. type T = { x: T }; ~~~~~~ -!!! error TS6133: 'T' is declared but its value is never read. +!!! error TS6196: 'T' is declared but never used. namespace N { N; } ~~~~~~~~~~~ !!! error TS6133: 'N' is declared but its value is never read. diff --git a/tests/baselines/reference/unusedClassesinModule1.errors.txt b/tests/baselines/reference/unusedClassesinModule1.errors.txt index 12b82ee97b6..488c434c537 100644 --- a/tests/baselines/reference/unusedClassesinModule1.errors.txt +++ b/tests/baselines/reference/unusedClassesinModule1.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedClassesinModule1.ts(2,5): error TS6133: 'Calculator' is declared but its value is never read. +tests/cases/compiler/unusedClassesinModule1.ts(2,5): error TS6196: 'Calculator' is declared but never used. ==== tests/cases/compiler/unusedClassesinModule1.ts (1 errors) ==== module A { class Calculator { ~~~~~~~~~~~~~~~~ -!!! error TS6133: 'Calculator' is declared but its value is never read. +!!! error TS6196: 'Calculator' is declared but never used. public handelChar() { } } diff --git a/tests/baselines/reference/unusedClassesinNamespace1.errors.txt b/tests/baselines/reference/unusedClassesinNamespace1.errors.txt index 4d4f26dde7b..44050f75b54 100644 --- a/tests/baselines/reference/unusedClassesinNamespace1.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace1.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedClassesinNamespace1.ts(2,5): error TS6133: 'c1' is declared but its value is never read. +tests/cases/compiler/unusedClassesinNamespace1.ts(2,5): error TS6196: 'c1' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace1.ts (1 errors) ==== namespace Validation { class c1 { ~~~~~~~~ -!!! error TS6133: 'c1' is declared but its value is never read. +!!! error TS6196: 'c1' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedClassesinNamespace2.errors.txt b/tests/baselines/reference/unusedClassesinNamespace2.errors.txt index c98aeb28369..6c6f5f815b6 100644 --- a/tests/baselines/reference/unusedClassesinNamespace2.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedClassesinNamespace2.ts(2,5): error TS6133: 'c1' is declared but its value is never read. +tests/cases/compiler/unusedClassesinNamespace2.ts(2,5): error TS6196: 'c1' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace2.ts (1 errors) ==== namespace Validation { class c1 { ~~~~~~~~ -!!! error TS6133: 'c1' is declared but its value is never read. +!!! error TS6196: 'c1' is declared but never used. } diff --git a/tests/baselines/reference/unusedClassesinNamespace4.errors.txt b/tests/baselines/reference/unusedClassesinNamespace4.errors.txt index 7545f0e2dde..209654569c9 100644 --- a/tests/baselines/reference/unusedClassesinNamespace4.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace4.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedClassesinNamespace4.ts(10,5): error TS6133: 'c3' is declared but its value is never read. +tests/cases/compiler/unusedClassesinNamespace4.ts(10,5): error TS6196: 'c3' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace4.ts (1 errors) ==== @@ -13,7 +13,7 @@ tests/cases/compiler/unusedClassesinNamespace4.ts(10,5): error TS6133: 'c3' is d class c3 extends c1 { ~~~~~~~~ -!!! error TS6133: 'c3' is declared but its value is never read. +!!! error TS6196: 'c3' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedClassesinNamespace5.errors.txt b/tests/baselines/reference/unusedClassesinNamespace5.errors.txt index 3512a1634c5..58cfa661603 100644 --- a/tests/baselines/reference/unusedClassesinNamespace5.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedClassesinNamespace5.ts(10,5): error TS6133: 'c3' is declared but its value is never read. +tests/cases/compiler/unusedClassesinNamespace5.ts(10,5): error TS6196: 'c3' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace5.ts (1 errors) ==== @@ -13,7 +13,7 @@ tests/cases/compiler/unusedClassesinNamespace5.ts(10,5): error TS6133: 'c3' is d class c3 { ~~~~~~~~ -!!! error TS6133: 'c3' is declared but its value is never read. +!!! error TS6196: 'c3' is declared but never used. public x: c1; } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt b/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt index 7d3dcf34830..3ddd1f12b1b 100644 --- a/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt +++ b/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt @@ -10,11 +10,11 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(17,13): error TS6133: 'un tests/cases/compiler/unusedIdentifiersConsolidated1.ts(24,13): error TS6133: 'unUsedPrivateFunction' is declared but its value is never read. tests/cases/compiler/unusedIdentifiersConsolidated1.ts(37,11): error TS6133: 'numberRegexp' is declared but its value is never read. tests/cases/compiler/unusedIdentifiersConsolidated1.ts(44,17): error TS6133: 'unUsedPrivateFunction' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(57,5): error TS6133: 'usedLocallyInterface2' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(64,5): error TS6133: 'dummy' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(67,5): error TS6133: 'unusedInterface' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(79,5): error TS6133: 'class3' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'interface5' is declared but its value is never read. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(57,5): error TS6196: 'usedLocallyInterface2' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(64,5): error TS6196: 'dummy' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(67,5): error TS6196: 'unusedInterface' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(79,5): error TS6196: 'class3' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6196: 'interface5' is declared but never used. ==== tests/cases/compiler/unusedIdentifiersConsolidated1.ts (17 errors) ==== @@ -100,7 +100,7 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'int interface usedLocallyInterface2 { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS6133: 'usedLocallyInterface2' is declared but its value is never read. +!!! error TS6196: 'usedLocallyInterface2' is declared but never used. someFunction(s1: string): void; } @@ -109,12 +109,12 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'int class dummy implements usedLocallyInterface { ~~~~~~~~~~~ -!!! error TS6133: 'dummy' is declared but its value is never read. +!!! error TS6196: 'dummy' is declared but never used. } interface unusedInterface { ~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS6133: 'unusedInterface' is declared but its value is never read. +!!! error TS6196: 'unusedInterface' is declared but never used. } } @@ -128,7 +128,7 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'int class class3 { ~~~~~~~~~~~~ -!!! error TS6133: 'class3' is declared but its value is never read. +!!! error TS6196: 'class3' is declared but never used. } export class class4 { @@ -150,6 +150,6 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6133: 'int interface interface5 { ~~~~~~~~~~~~~~~~~~~~ -!!! error TS6133: 'interface5' is declared but its value is never read. +!!! error TS6196: 'interface5' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt index e5e01491727..0fe77374c4d 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedInterfaceinNamespace1.ts(2,5): error TS6133: 'i1' is declared but its value is never read. +tests/cases/compiler/unusedInterfaceinNamespace1.ts(2,5): error TS6196: 'i1' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace1.ts (1 errors) ==== namespace Validation { interface i1 { ~~~~~~~~~~~~ -!!! error TS6133: 'i1' is declared but its value is never read. +!!! error TS6196: 'i1' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt index 3839b63f507..40e224358af 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/unusedInterfaceinNamespace2.ts(2,5): error TS6133: 'i1' is declared but its value is never read. +tests/cases/compiler/unusedInterfaceinNamespace2.ts(2,5): error TS6196: 'i1' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace2.ts (1 errors) ==== namespace Validation { interface i1 { ~~~~~~~~~~~~ -!!! error TS6133: 'i1' is declared but its value is never read. +!!! error TS6196: 'i1' is declared but never used. } diff --git a/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt index 76d32cdf583..206dd51c3e5 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,5): error TS6133: 'i3' is declared but its value is never read. +tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,5): error TS6196: 'i3' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace3.ts (1 errors) ==== @@ -13,7 +13,7 @@ tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,5): error TS6133: 'i3' is interface i3 extends i1 { ~~~~~~~~~~~~ -!!! error TS6133: 'i3' is declared but its value is never read. +!!! error TS6196: 'i3' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedLocalsAndParameters.errors.txt b/tests/baselines/reference/unusedLocalsAndParameters.errors.txt index 7ee0e0b8cb9..e9656c6f669 100644 --- a/tests/baselines/reference/unusedLocalsAndParameters.errors.txt +++ b/tests/baselines/reference/unusedLocalsAndParameters.errors.txt @@ -2,7 +2,7 @@ tests/cases/compiler/unusedLocalsAndParameters.ts(4,12): error TS6133: 'a' is de tests/cases/compiler/unusedLocalsAndParameters.ts(9,22): error TS6133: 'a' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(15,5): error TS6133: 'farrow' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(15,15): error TS6133: 'a' is declared but its value is never read. -tests/cases/compiler/unusedLocalsAndParameters.ts(18,1): error TS6133: 'C' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndParameters.ts(18,1): error TS6196: 'C' is declared but never used. tests/cases/compiler/unusedLocalsAndParameters.ts(20,12): error TS6133: 'a' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(23,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/compiler/unusedLocalsAndParameters.ts(23,11): error TS6133: 'v' is declared but its value is never read. @@ -52,7 +52,7 @@ tests/cases/compiler/unusedLocalsAndParameters.ts(80,9): error TS6133: 'x' is de class C { ~~~~~~~ -!!! error TS6133: 'C' is declared but its value is never read. +!!! error TS6196: 'C' is declared but never used. // Method declaration paramter method(a) { ~ diff --git a/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt b/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt index 31c825ce906..f86ec0d1cc7 100644 --- a/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt +++ b/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt @@ -1,13 +1,13 @@ -tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(2,1): error TS6133: 'handler1' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(2,1): error TS6196: 'handler1' is declared but never used. tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(5,1): error TS6133: 'foo' is declared but its value is never read. -tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(6,5): error TS6133: 'handler2' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(6,5): error TS6196: 'handler2' is declared but never used. ==== tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts (3 errors) ==== // unused type handler1 = () => void; ~~~~~~~~~~~~~ -!!! error TS6133: 'handler1' is declared but its value is never read. +!!! error TS6196: 'handler1' is declared but never used. function foo() { @@ -15,7 +15,7 @@ tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(6,5): error TS6133 !!! error TS6133: 'foo' is declared but its value is never read. type handler2 = () => void; ~~~~~~~~~~~~~ -!!! error TS6133: 'handler2' is declared but its value is never read. +!!! error TS6196: 'handler2' is declared but never used. foo(); } From b72abdb1204fbebd657bdb7eb6c0b028ebcd5089 Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 24 Apr 2018 16:10:31 +0000 Subject: [PATCH 175/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 12 +++++++ .../diagnosticMessages.generated.json.lcl | 33 ++++++++++--------- .../diagnosticMessages.generated.json.lcl | 12 +++++++ .../diagnosticMessages.generated.json.lcl | 9 +++++ 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 23b68db43f8..f6f14d4a402 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -906,6 +906,9 @@ + + + @@ -1008,6 +1011,9 @@ + + + @@ -6498,6 +6504,12 @@ + + + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index ca47b5dac95..5f93b90c20e 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -912,6 +912,15 @@ + + + + + + + + + @@ -1008,27 +1017,15 @@ - + - + - + - - - - - - - - - - - - @@ -6516,6 +6513,12 @@ + + + + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 07300f3ab7c..235f19b459f 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -906,6 +906,9 @@ + + + @@ -1008,6 +1011,9 @@ + + + @@ -6498,6 +6504,12 @@ + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index dc4c01fcad4..c10ba98b4e0 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -905,6 +905,9 @@ + + + @@ -6497,6 +6500,12 @@ + + + + + + From 59765e2d86a7e36b827043a5ca75d49d2a7a88a3 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 24 Apr 2018 09:41:47 -0700 Subject: [PATCH 176/229] goToDefinition: Also add definitions for symbol if it does not match the signature symbol (#23657) --- src/services/goToDefinition.ts | 40 +++++++++++-------- ...ToDefinitionNewExpressionTargetNotClass.ts | 4 +- .../fourslash/goToDefinitionSignatureAlias.ts | 15 +++++++ tests/cases/fourslash/goToDefinition_super.ts | 2 +- .../tsxGoToDefinitionUnionElementType1.ts | 6 +-- 5 files changed, 45 insertions(+), 22 deletions(-) create mode 100644 tests/cases/fourslash/goToDefinitionSignatureAlias.ts diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index f97a8338b05..977f9617353 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -18,13 +18,7 @@ namespace ts.GoToDefinition { } const typeChecker = program.getTypeChecker(); - - const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); - if (calledDeclaration) { - return [createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration)]; - } - - let symbol = typeChecker.getSymbolAtLocation(node); + const symbol = getSymbol(node, typeChecker); // Could not find a symbol e.g. node is string or number keyword, // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol @@ -32,15 +26,14 @@ namespace ts.GoToDefinition { return getDefinitionInfoForIndexSignatures(node, typeChecker); } - // If this is an alias, and the request came at the declaration location - // get the aliased symbol instead. This allows for goto def on an import e.g. - // import {A, B} from "mod"; - // to jump to the implementation directly. - if (symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) { - const aliased = typeChecker.getAliasedSymbol(symbol); - if (aliased.declarations) { - symbol = aliased; - } + const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); + if (calledDeclaration) { + const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration); + // For a function, if this is the original function definition, return just sigInfo. + // If this is the original constructor definition, parent is the class. + return typeChecker.getRootSymbols(symbol).some(s => calledDeclaration.symbol === s || calledDeclaration.symbol.parent === s) + ? [sigInfo] + : [sigInfo, ...getDefinitionFromSymbol(typeChecker, symbol, node)]; } // Because name in short-hand property assignment has two different meanings: property name and property value, @@ -158,6 +151,21 @@ namespace ts.GoToDefinition { }); } + function getSymbol(node: Node, checker: TypeChecker): Symbol | undefined { + const symbol = checker.getSymbolAtLocation(node); + // If this is an alias, and the request came at the declaration location + // get the aliased symbol instead. This allows for goto def on an import e.g. + // import {A, B} from "mod"; + // to jump to the implementation directly. + if (symbol && symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) { + const aliased = checker.getAliasedSymbol(symbol); + if (aliased.declarations) { + return aliased; + } + } + return symbol; + } + // Go to the original declaration for cases: // // (1) when the aliased symbol was declared in the location(parent). diff --git a/tests/cases/fourslash/goToDefinitionNewExpressionTargetNotClass.ts b/tests/cases/fourslash/goToDefinitionNewExpressionTargetNotClass.ts index 02a6dca9d52..00f83323a0b 100644 --- a/tests/cases/fourslash/goToDefinitionNewExpressionTargetNotClass.ts +++ b/tests/cases/fourslash/goToDefinitionNewExpressionTargetNotClass.ts @@ -2,7 +2,7 @@ ////class C2 { ////} -////let I: { +////let /*I*/I: { //// /*constructSignature*/new(): C2; ////}; ////new [|/*invokeExpression1*/I|](); @@ -11,6 +11,6 @@ ////new [|/*invokeExpression2*/I2|](); verify.goToDefinition({ - invokeExpression1: "constructSignature", + invokeExpression1: ["constructSignature", "I"], invokeExpression2: "symbolDeclaration" }); diff --git a/tests/cases/fourslash/goToDefinitionSignatureAlias.ts b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts new file mode 100644 index 00000000000..07a5678f5d2 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionSignatureAlias.ts @@ -0,0 +1,15 @@ +/// + +////function /*f*/f() {} +////const /*g*/g = f; +////const /*h*/h = g; + +////[|/*useF*/f|](); +////[|/*useG*/g|](); +////[|/*useH*/h|](); + +verify.goToDefinition({ + useF: "f", + useG: ["f", "g"], + useH: ["f", "h"], +}); diff --git a/tests/cases/fourslash/goToDefinition_super.ts b/tests/cases/fourslash/goToDefinition_super.ts index 22f00aff7dc..edc7a40c376 100644 --- a/tests/cases/fourslash/goToDefinition_super.ts +++ b/tests/cases/fourslash/goToDefinition_super.ts @@ -22,7 +22,7 @@ verify.goToDefinition({ // Super in call position goes to constructor. - super: "ctr", + super: ["ctr", "B"], // Super in any other position goes to the superclass. superExpression: "B", superBroken: [] diff --git a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts index d6b5dfab709..0e899c71d2b 100644 --- a/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts +++ b/tests/cases/fourslash/tsxGoToDefinitionUnionElementType1.ts @@ -18,9 +18,9 @@ //// return

World

; //// } -//// var SFCComp = SFC1 || SFC2; +//// var /*def*/SFCComp = SFC1 || SFC2; //// <[|SFC/*one*/Comp|] x /> verify.goToDefinition({ - "one": "pt1" -}) \ No newline at end of file + "one": ["pt1", "def"], +}); From e71afc32ad8cb4d1e48444fb38a0a2da4d39f989 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Apr 2018 10:02:34 -0700 Subject: [PATCH 177/229] Reinstate type simplification for 'keyof T[K]' as target in relation --- src/compiler/checker.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75f8715fca7..4e1d71c3d7a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10482,11 +10482,14 @@ namespace ts { } } // A type S is assignable to keyof T if S is assignable to keyof C, where C is the - // constraint of T. - const constraint = getConstraintForRelation((target).type); - if (constraint) { - if (result = isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors)) { - return result; + // simplified form of T or, if T doesn't simplify, the constraint of T. + if (relation !== definitelyAssignableRelation) { + const simplified = getSimplifiedType((target).type); + const constraint = simplified !== (target).type ? simplified : getConstraintOfType((target).type); + if (constraint) { + if (result = isRelatedTo(source, getIndexType(constraint, (target as IndexType).stringsOnly), reportErrors)) { + return result; + } } } } From 57ef618120f9f7463bf9cf0edcbf8be793287e59 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Apr 2018 10:02:47 -0700 Subject: [PATCH 178/229] Add regression test --- .../conformance/types/keyof/keyofAndIndexedAccess.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index e0c1f544d97..6388245316d 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -567,3 +567,12 @@ function f3>(t: T, k: K, tk: T[K]): void { type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] } + +// Repros from #23592 + +type Example = { [K in keyof T]: T[K]["prop"] }; +type Result = Example<{ a: { prop: string }; b: { prop: number } }>; + +type Helper2 = { [K in keyof T]: Extract }; +type Example2 = { [K in keyof Helper2]: Helper2[K]["prop"] }; +type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>; From 08c288d4f99e8903d4e92cb96c3776c7d8bddc42 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Apr 2018 10:02:54 -0700 Subject: [PATCH 179/229] Accept new baselines --- .../reference/keyofAndIndexedAccess.js | 40 +++++++++++++++ .../reference/keyofAndIndexedAccess.symbols | 49 +++++++++++++++++++ .../reference/keyofAndIndexedAccess.types | 49 +++++++++++++++++++ 3 files changed, 138 insertions(+) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index 422cef5a574..bd8404f9ae0 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -565,6 +565,15 @@ function f3>(t: T, k: K, tk: T[K]): void { type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] } + +// Repros from #23592 + +type Example = { [K in keyof T]: T[K]["prop"] }; +type Result = Example<{ a: { prop: string }; b: { prop: number } }>; + +type Helper2 = { [K in keyof T]: Extract }; +type Example2 = { [K in keyof Helper2]: Helper2[K]["prop"] }; +type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>; //// [keyofAndIndexedAccess.js] @@ -1212,3 +1221,34 @@ declare function f3>(t: T, k: K, tk: T[K]) declare type Predicates = { [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]; }; +declare type Example = { + [K in keyof T]: T[K]["prop"]; +}; +declare type Result = Example<{ + a: { + prop: string; + }; + b: { + prop: number; + }; +}>; +declare type Helper2 = { + [K in keyof T]: Extract; +}; +declare type Example2 = { + [K in keyof Helper2]: Helper2[K]["prop"]; +}; +declare type Result2 = Example2<{ + 1: { + prop: string; + }; + 2: { + prop: number; + }; +}>; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index b1206a49388..118a6fb3bd6 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -2010,3 +2010,52 @@ type Predicates = { >T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3)) } +// Repros from #23592 + +type Example = { [K in keyof T]: T[K]["prop"] }; +>Example : Symbol(Example, Decl(keyofAndIndexedAccess.ts, 565, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 26)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 569, 42)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 63)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 63)) + +type Result = Example<{ a: { prop: string }; b: { prop: number } }>; +>Result : Symbol(Result, Decl(keyofAndIndexedAccess.ts, 569, 93)) +>Example : Symbol(Example, Decl(keyofAndIndexedAccess.ts, 565, 1)) +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 570, 23)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 570, 28)) +>b : Symbol(b, Decl(keyofAndIndexedAccess.ts, 570, 44)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 570, 49)) + +type Helper2 = { [K in keyof T]: Extract }; +>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 572, 21)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 572, 21)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 572, 51)) + +type Example2 = { [K in keyof Helper2]: Helper2[K]["prop"] }; +>Example2 : Symbol(Example2, Decl(keyofAndIndexedAccess.ts, 572, 67)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 573, 22)) +>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14)) +>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 573, 22)) + +type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>; +>Result2 : Symbol(Result2, Decl(keyofAndIndexedAccess.ts, 573, 70)) +>Example2 : Symbol(Example2, Decl(keyofAndIndexedAccess.ts, 572, 67)) +>1 : Symbol(1, Decl(keyofAndIndexedAccess.ts, 574, 25)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 574, 30)) +>2 : Symbol(2, Decl(keyofAndIndexedAccess.ts, 574, 46)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 574, 51)) + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 4e41b58e664..3e857c6dcd5 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -2345,3 +2345,52 @@ type Predicates = { >T : T } +// Repros from #23592 + +type Example = { [K in keyof T]: T[K]["prop"] }; +>Example : Example +>T : T +>K : K +>T : T +>prop : any +>K : K +>T : T +>T : T +>K : K + +type Result = Example<{ a: { prop: string }; b: { prop: number } }>; +>Result : Example<{ a: { prop: string; }; b: { prop: number; }; }> +>Example : Example +>a : { prop: string; } +>prop : string +>b : { prop: number; } +>prop : number + +type Helper2 = { [K in keyof T]: Extract }; +>Helper2 : Helper2 +>T : T +>K : K +>T : T +>Extract : Extract +>T : T +>K : K +>prop : any + +type Example2 = { [K in keyof Helper2]: Helper2[K]["prop"] }; +>Example2 : Example2 +>T : T +>K : K +>Helper2 : Helper2 +>T : T +>Helper2 : Helper2 +>T : T +>K : K + +type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>; +>Result2 : Example2<{ 1: { prop: string; }; 2: { prop: number; }; }> +>Example2 : Example2 +>1 : { prop: string; } +>prop : string +>2 : { prop: number; } +>prop : number + From a55febda779bd9c24b1d3b454860a40b351c158e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 24 Apr 2018 12:21:36 -0700 Subject: [PATCH 180/229] Make 'ImportMeta' more minimal. --- src/lib/es5.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index cd4be60e8e4..55c184f672f 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -505,8 +505,13 @@ interface TemplateStringsArray extends ReadonlyArray { readonly raw: ReadonlyArray; } +/** + * The type of `import.meta`. + * + * If you need to declare that a given property exists on `import.meta`, + * this type may be augmented via interface merging. + */ interface ImportMeta { - [propertyName: string]: any; } interface Math { From 28f8d7532fac10e68da376bb355bf87212901f8b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 24 Apr 2018 12:39:41 -0700 Subject: [PATCH 181/229] Accepted baselines. --- tests/baselines/reference/importMeta.errors.txt | 16 ++++++++++++++-- .../baselines/reference/importMetaES5.errors.txt | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/importMeta.errors.txt b/tests/baselines/reference/importMeta.errors.txt index 2c44876fe23..999c883f266 100644 --- a/tests/baselines/reference/importMeta.errors.txt +++ b/tests/baselines/reference/importMeta.errors.txt @@ -1,6 +1,10 @@ error TS2468: Cannot find global value 'Promise'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. +tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'. +tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(3,23): error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(2,22): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? @@ -8,15 +12,19 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS !!! error TS2468: Cannot find global value 'Promise'. -==== tests/cases/conformance/es2019/importMeta/example.ts (1 errors) ==== +==== tests/cases/conformance/es2019/importMeta/example.ts (3 errors) ==== // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example (async () => { ~~~~~~~~~~~~~ !!! error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); + ~~~ +!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'. const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. const image = new Image(); image.src = URL.createObjectURL(blob); @@ -43,8 +51,12 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS ~~~~~~ !!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? -==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (1 errors) ==== +==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (3 errors) ==== export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; + ~~~~ +!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'. + ~~~~ +!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'. import.meta = foo; ~~~~~~~~~~~ !!! error TS2364: The left-hand side of an assignment expression must be a variable or a property access. diff --git a/tests/baselines/reference/importMetaES5.errors.txt b/tests/baselines/reference/importMetaES5.errors.txt index 46cc1107f69..71b67efae01 100644 --- a/tests/baselines/reference/importMetaES5.errors.txt +++ b/tests/baselines/reference/importMetaES5.errors.txt @@ -1,13 +1,17 @@ error TS2468: Cannot find global value 'Promise'. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,32): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,44): error TS2339: Property 'blah' does not exist on type 'ImportMeta'. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,51): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,63): error TS2339: Property 'blue' does not exist on type 'ImportMeta'. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(1,70): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(2,1): error TS2364: The left-hand side of an assignment expression must be a variable or a property access. tests/cases/conformance/es2019/importMeta/assignmentTargets.ts(11,21): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. tests/cases/conformance/es2019/importMeta/example.ts(2,2): error TS2705: An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option. tests/cases/conformance/es2019/importMeta/example.ts(3,59): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/example.ts(3,71): error TS2339: Property 'url' does not exist on type 'ImportMeta'. tests/cases/conformance/es2019/importMeta/example.ts(6,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. +tests/cases/conformance/es2019/importMeta/example.ts(6,28): error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(1,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,16): error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. tests/cases/conformance/es2019/importMeta/moduleLookingFile01.ts(2,23): error TS17012: 'metal' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? @@ -21,7 +25,7 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS !!! error TS2468: Cannot find global value 'Promise'. -==== tests/cases/conformance/es2019/importMeta/example.ts (3 errors) ==== +==== tests/cases/conformance/es2019/importMeta/example.ts (5 errors) ==== // Adapted from https://github.com/tc39/proposal-import-meta/tree/c3902a9ffe2e69a7ac42c19d7ea74cbdcea9b7fb#example (async () => { ~~~~~~~~~~~~~ @@ -29,11 +33,15 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS const response = await fetch(new URL("../hamsters.jpg", import.meta.url).toString()); ~~~~~~~~~~~ !!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~ +!!! error TS2339: Property 'url' does not exist on type 'ImportMeta'. const blob = await response.blob(); const size = import.meta.scriptElement.dataset.size || 300; ~~~~~~~~~~~ !!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'scriptElement' does not exist on type 'ImportMeta'. const image = new Image(); image.src = URL.createObjectURL(blob); @@ -72,12 +80,16 @@ tests/cases/conformance/es2019/importMeta/scriptLookingFile01.ts(3,22): error TS ~~~~~~ !!! error TS17012: 'import' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? -==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (6 errors) ==== +==== tests/cases/conformance/es2019/importMeta/assignmentTargets.ts (8 errors) ==== export const foo: ImportMeta = import.meta.blah = import.meta.blue = import.meta; ~~~~~~~~~~~ !!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~ +!!! error TS2339: Property 'blah' does not exist on type 'ImportMeta'. ~~~~~~~~~~~ !!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. + ~~~~ +!!! error TS2339: Property 'blue' does not exist on type 'ImportMeta'. ~~~~~~~~~~~ !!! error TS1343: The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options. import.meta = foo; From ef8d5094b41c62ab484753acd32d872508423284 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Apr 2018 14:57:27 -0700 Subject: [PATCH 182/229] Properly check relationships for intersections with union constraints --- src/compiler/checker.ts | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 00ddb416e22..8d4301c8722 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6428,6 +6428,26 @@ namespace ts { return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type); } + function getUnionConstraintOfIntersection(type: IntersectionType) { + let constraints: Type[]; + for (const t of type.types) { + if (t.flags & TypeFlags.Instantiable) { + const baseConstraint = getBaseConstraintOfType(t); + if (!(baseConstraint.flags & TypeFlags.Union)) { + return undefined; + } + constraints = append(constraints, baseConstraint); + } + } + if (constraints) { + const constraint = getIntersectionType(constraints); + if (constraint.flags & TypeFlags.Union) { + return constraint; + } + } + return undefined; + } + function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type: Type) { if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) { const constraint = getResolvedBaseConstraint(type); @@ -10125,6 +10145,21 @@ namespace ts { errorInfo = saveErrorInfo; } } + if (!result && source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Union) { + // The combined constraint of an intersection type is the intersection of the constraints of + // the constituents. Since we break down union types before intersection types, if the target + // type is a union type and the source type is an intersection type with a combined constraint + // that is a union type, we need an extra check to see if the combined constraint is related to + // the target. For example, given two type variables T and U, each with the constraint + // 'string | number', the combined constraint of 'T & U' is 'string | number' and we need to + // check this constraint against the union on the target side. + const constraint = getUnionConstraintOfIntersection(source); + if (constraint) { + if (result = isRelatedTo(constraint, target, reportErrors)) { + errorInfo = saveErrorInfo; + } + } + } } isIntersectionConstituent = saveIsIntersectionConstituent; From dfbc842164dbb6ebc51bf670d4fe443c0487998a Mon Sep 17 00:00:00 2001 From: csigs Date: Tue, 24 Apr 2018 22:11:15 +0000 Subject: [PATCH 183/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ .../diagnosticMessages.generated.json.lcl | 3 +++ 4 files changed, 39 insertions(+) diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5798b852bbe..a2fd58ac665 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -903,6 +903,9 @@ + + + @@ -1005,6 +1008,9 @@ + + + @@ -6492,6 +6498,12 @@
+ + + + + + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 6b949870bbd..f1cec4555ac 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -915,6 +915,9 @@ + + + @@ -1017,6 +1020,9 @@ + + + @@ -6507,6 +6513,12 @@ + + + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 94427fcd4ca..f8a6325f4a1 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -896,6 +896,9 @@ + + + @@ -998,6 +1001,9 @@ + + + @@ -6485,6 +6491,12 @@ + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index c10ba98b4e0..3be5ddb0dbb 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1010,6 +1010,9 @@ + + + From d90d6b9277953812d741b5fd43f097ea59d5d247 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Apr 2018 15:55:15 -0700 Subject: [PATCH 184/229] Remove more intersections with empty value domains from union types --- src/compiler/checker.ts | 15 ++++++++++++--- src/compiler/types.ts | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8d4301c8722..0618abe75bb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7917,8 +7917,13 @@ namespace ts { return binarySearch(types, type, getTypeId, compareValues) >= 0; } - // Return true if the given intersection type contains (a) more than one unit type or (b) an object - // type and a nullable type (null or undefined). + // Return true if the given intersection type contains + // more than one unit type or, + // an object type and a nullable type (null or undefined), or + // a string-like type and a non-string-like primitive type, or + // a number-like type and a non-number-like primitive type, or + // a symbol-like type and a non-symbol-like primitive type, or + // a void-like type and a non-void-like primitive type. function isEmptyIntersectionType(type: IntersectionType) { let combined: TypeFlags = 0; for (const t of type.types) { @@ -7926,7 +7931,11 @@ namespace ts { return true; } combined |= t.flags; - if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive)) { + if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive) || + combined & TypeFlags.StringLike && combined & (TypeFlags.Primitive & ~TypeFlags.StringLike) || + combined & TypeFlags.NumberLike && combined & (TypeFlags.Primitive & ~TypeFlags.NumberLike) || + combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.Primitive & ~TypeFlags.ESSymbolLike) || + combined & TypeFlags.VoidLike && combined & (TypeFlags.Primitive & ~TypeFlags.VoidLike)) { return true; } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 06f15e1d77a..fd3a58bc5ea 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3613,6 +3613,7 @@ namespace ts { BooleanLike = Boolean | BooleanLiteral, EnumLike = Enum | EnumLiteral, ESSymbolLike = ESSymbol | UniqueESSymbol, + VoidLike = Void | Undefined, UnionOrIntersection = Union | Intersection, StructuredType = Object | Union | Intersection, TypeVariable = TypeParameter | IndexedAccess, From e091e350bb2c58e6c922b61f3928f72e7b536b0e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Apr 2018 15:56:46 -0700 Subject: [PATCH 185/229] Accept new baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../errorMessagesIntersectionTypes04.errors.txt | 7 +------ .../reference/errorMessagesIntersectionTypes04.types | 6 +++--- .../reference/keyofAndIndexedAccessErrors.types | 8 ++++---- .../switchCaseWithIntersectionTypes01.errors.txt | 9 +-------- .../reference/switchCaseWithIntersectionTypes01.types | 4 ++-- tests/baselines/reference/typeGuardsWithInstanceOf.types | 4 ++-- 8 files changed, 15 insertions(+), 25 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 9bd2de6aa41..fb261ef4b46 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2105,6 +2105,7 @@ declare namespace ts { BooleanLike = 136, EnumLike = 272, ESSymbolLike = 1536, + VoidLike = 6144, UnionOrIntersection = 393216, StructuredType = 458752, TypeVariable = 1081344, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3c47002061f..39f811bcec5 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2105,6 +2105,7 @@ declare namespace ts { BooleanLike = 136, EnumLike = 272, ESSymbolLike = 1536, + VoidLike = 6144, UnionOrIntersection = 393216, StructuredType = 458752, TypeVariable = 1081344, diff --git a/tests/baselines/reference/errorMessagesIntersectionTypes04.errors.txt b/tests/baselines/reference/errorMessagesIntersectionTypes04.errors.txt index d2e81844da1..25fdc65f5e8 100644 --- a/tests/baselines/reference/errorMessagesIntersectionTypes04.errors.txt +++ b/tests/baselines/reference/errorMessagesIntersectionTypes04.errors.txt @@ -1,11 +1,9 @@ tests/cases/compiler/errorMessagesIntersectionTypes04.ts(17,5): error TS2322: Type 'A & B' is not assignable to type 'number'. tests/cases/compiler/errorMessagesIntersectionTypes04.ts(18,5): error TS2322: Type 'A & B' is not assignable to type 'boolean'. tests/cases/compiler/errorMessagesIntersectionTypes04.ts(19,5): error TS2322: Type 'A & B' is not assignable to type 'string'. -tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'. - Type 'number & true' is not assignable to type 'string'. -==== tests/cases/compiler/errorMessagesIntersectionTypes04.ts (4 errors) ==== +==== tests/cases/compiler/errorMessagesIntersectionTypes04.ts (3 errors) ==== interface A { a; } @@ -33,7 +31,4 @@ tests/cases/compiler/errorMessagesIntersectionTypes04.ts(21,5): error TS2322: Ty !!! error TS2322: Type 'A & B' is not assignable to type 'string'. str = num_and_bool; - ~~~ -!!! error TS2322: Type '(number & true) | (number & false)' is not assignable to type 'string'. -!!! error TS2322: Type 'number & true' is not assignable to type 'string'. } \ No newline at end of file diff --git a/tests/baselines/reference/errorMessagesIntersectionTypes04.types b/tests/baselines/reference/errorMessagesIntersectionTypes04.types index 9d8db5dba3d..b24597d4b33 100644 --- a/tests/baselines/reference/errorMessagesIntersectionTypes04.types +++ b/tests/baselines/reference/errorMessagesIntersectionTypes04.types @@ -36,7 +36,7 @@ function f(): void { >B : B let num_and_bool: number & boolean; ->num_and_bool : (number & true) | (number & false) +>num_and_bool : never num = a_and_b; >num = a_and_b : A & B @@ -54,7 +54,7 @@ function f(): void { >a_and_b : A & B str = num_and_bool; ->str = num_and_bool : (number & true) | (number & false) +>str = num_and_bool : never >str : string ->num_and_bool : (number & true) | (number & false) +>num_and_bool : never } diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 6a474c18107..6f90eb2c187 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -34,19 +34,19 @@ type T02 = keyof keyof Object; >Object : Object type T03 = keyof keyof keyof Object; ->T03 : "toString" | "valueOf" | ("toString" & number) | ("toLocaleString" & number) | ("valueOf" & number) | ("toFixed" & number) | ("toExponential" & number) | ("toPrecision" & number) +>T03 : "toString" | "valueOf" >Object : Object type T04 = keyof keyof keyof keyof Object; ->T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | ("toString" & number) | ("valueOf" & number) | (number & "length") | (number & "toString") | (number & "toLocaleString") | (number & "valueOf") | (number & "charAt") | (number & "charCodeAt") | (number & "concat") | (number & "indexOf") | (number & "lastIndexOf") | (number & "localeCompare") | (number & "match") | (number & "replace") | (number & "search") | (number & "slice") | (number & "split") | (number & "substring") | (number & "toLowerCase") | (number & "toLocaleLowerCase") | (number & "toUpperCase") | (number & "toLocaleUpperCase") | (number & "trim") | (number & "substr") | (number & "toFixed") | (number & "toExponential") | (number & "toPrecision") | ("length" & number) | ("charAt" & number) | ("charCodeAt" & number) | ("concat" & number) | ("indexOf" & number) | ("lastIndexOf" & number) | ("localeCompare" & number) | ("match" & number) | ("replace" & number) | ("search" & number) | ("slice" & number) | ("split" & number) | ("substring" & number) | ("toLowerCase" & number) | ("toLocaleLowerCase" & number) | ("toUpperCase" & number) | ("toLocaleUpperCase" & number) | ("trim" & number) | ("substr" & number) +>T04 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" >Object : Object type T05 = keyof keyof keyof keyof keyof Object; ->T05 : "toString" | "valueOf" | ("toString" & number) | ("toLocaleString" & number) | ("valueOf" & number) | ("toFixed" & number) | ("toExponential" & number) | ("toPrecision" & number) +>T05 : "toString" | "valueOf" >Object : Object type T06 = keyof keyof keyof keyof keyof keyof Object; ->T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" | ("toString" & number) | ("valueOf" & number) | (number & "length") | (number & "toString") | (number & "toLocaleString") | (number & "valueOf") | (number & "charAt") | (number & "charCodeAt") | (number & "concat") | (number & "indexOf") | (number & "lastIndexOf") | (number & "localeCompare") | (number & "match") | (number & "replace") | (number & "search") | (number & "slice") | (number & "split") | (number & "substring") | (number & "toLowerCase") | (number & "toLocaleLowerCase") | (number & "toUpperCase") | (number & "toLocaleUpperCase") | (number & "trim") | (number & "substr") | (number & "toFixed") | (number & "toExponential") | (number & "toPrecision") | ("length" & number) | ("charAt" & number) | ("charCodeAt" & number) | ("concat" & number) | ("indexOf" & number) | ("lastIndexOf" & number) | ("localeCompare" & number) | ("match" & number) | ("replace" & number) | ("search" & number) | ("slice" & number) | ("split" & number) | ("substring" & number) | ("toLowerCase" & number) | ("toLocaleLowerCase" & number) | ("toUpperCase" & number) | ("toLocaleUpperCase" & number) | ("trim" & number) | ("substr" & number) +>T06 : number | "length" | "toString" | "valueOf" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | "toLowerCase" | "toLocaleLowerCase" | "toUpperCase" | "toLocaleUpperCase" | "trim" | "substr" >Object : Object type T10 = Shape["name"]; diff --git a/tests/baselines/reference/switchCaseWithIntersectionTypes01.errors.txt b/tests/baselines/reference/switchCaseWithIntersectionTypes01.errors.txt index 3aca9d926b7..380e98c3c3d 100644 --- a/tests/baselines/reference/switchCaseWithIntersectionTypes01.errors.txt +++ b/tests/baselines/reference/switchCaseWithIntersectionTypes01.errors.txt @@ -1,10 +1,7 @@ -tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(18,10): error TS2678: Type '(number & true) | (number & false)' is not comparable to type 'string & number'. - Type 'number & false' is not comparable to type 'string & number'. - Type 'number & false' is not comparable to type 'string'. tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts(22,10): error TS2678: Type 'boolean' is not comparable to type 'string & number'. -==== tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts (2 errors) ==== +==== tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithIntersectionTypes01.ts (1 errors) ==== var strAndNum: string & number; var numAndBool: number & boolean; var str: string; @@ -23,10 +20,6 @@ tests/cases/conformance/types/typeRelationships/comparable/switchCaseWithInterse // Overlap in constituents case numAndBool: - ~~~~~~~~~~ -!!! error TS2678: Type '(number & true) | (number & false)' is not comparable to type 'string & number'. -!!! error TS2678: Type 'number & false' is not comparable to type 'string & number'. -!!! error TS2678: Type 'number & false' is not comparable to type 'string'. break; // No relation diff --git a/tests/baselines/reference/switchCaseWithIntersectionTypes01.types b/tests/baselines/reference/switchCaseWithIntersectionTypes01.types index 4a578f22319..9ba884985dc 100644 --- a/tests/baselines/reference/switchCaseWithIntersectionTypes01.types +++ b/tests/baselines/reference/switchCaseWithIntersectionTypes01.types @@ -3,7 +3,7 @@ var strAndNum: string & number; >strAndNum : string & number var numAndBool: number & boolean; ->numAndBool : (number & true) | (number & false) +>numAndBool : never var str: string; >str : string @@ -34,7 +34,7 @@ switch (strAndNum) { // Overlap in constituents case numAndBool: ->numAndBool : (number & true) | (number & false) +>numAndBool : never break; diff --git a/tests/baselines/reference/typeGuardsWithInstanceOf.types b/tests/baselines/reference/typeGuardsWithInstanceOf.types index 7fce8cd4559..3fd47f43fc3 100644 --- a/tests/baselines/reference/typeGuardsWithInstanceOf.types +++ b/tests/baselines/reference/typeGuardsWithInstanceOf.types @@ -25,7 +25,7 @@ if (!(result instanceof RegExp)) { } else if (!result.global) { >!result.global : boolean ->result.global : (string & true) | (string & false) +>result.global : never >result : I & RegExp ->global : (string & true) | (string & false) +>global : never } From 50c7ff79d0cfc44716df8c9ab512f5fff432a32d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Apr 2018 15:57:17 -0700 Subject: [PATCH 186/229] Add tests --- .../intersectionWithUnionConstraint.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts diff --git a/tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts b/tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts new file mode 100644 index 00000000000..b406dd91586 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts @@ -0,0 +1,24 @@ +// @strict: true + +function f1(x: T & U) { + // Combined constraint of 'T & U' is 'string | number' + let y: string | number = x; +} + +function f2(x: T & U) { + let y1: string | number = x; // Error + let y2: string | null = x; // Error + let y3: string | undefined = x; + let y4: number | null = x; // Error + let y5: number | undefined = x; // Error + let y6: null | undefined = x; // Error +} + +type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined + +// Repro from #23648 + +type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } + +type UnexpectedError = T +type NoErrorHere = T From b78054d9c3a76c64eca763bdaed5813b064e8fd2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Apr 2018 15:57:26 -0700 Subject: [PATCH 187/229] Accept new baselines --- ...intersectionWithUnionConstraint.errors.txt | 71 ++++++++++++++++ .../intersectionWithUnionConstraint.js | 39 +++++++++ .../intersectionWithUnionConstraint.symbols | 78 +++++++++++++++++ .../intersectionWithUnionConstraint.types | 83 +++++++++++++++++++ 4 files changed, 271 insertions(+) create mode 100644 tests/baselines/reference/intersectionWithUnionConstraint.errors.txt create mode 100644 tests/baselines/reference/intersectionWithUnionConstraint.js create mode 100644 tests/baselines/reference/intersectionWithUnionConstraint.symbols create mode 100644 tests/baselines/reference/intersectionWithUnionConstraint.types diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt b/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt new file mode 100644 index 00000000000..8892e412805 --- /dev/null +++ b/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt @@ -0,0 +1,71 @@ +tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(7,9): error TS2322: Type 'T & U' is not assignable to type 'string | number'. + Type 'string | undefined' is not assignable to type 'string | number'. + Type 'undefined' is not assignable to type 'string | number'. + Type 'T & U' is not assignable to type 'number'. +tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(8,9): error TS2322: Type 'T & U' is not assignable to type 'string | null'. + Type 'string | undefined' is not assignable to type 'string | null'. + Type 'undefined' is not assignable to type 'string | null'. + Type 'T & U' is not assignable to type 'string'. +tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(10,9): error TS2322: Type 'T & U' is not assignable to type 'number | null'. + Type 'string | undefined' is not assignable to type 'number | null'. + Type 'undefined' is not assignable to type 'number | null'. + Type 'T & U' is not assignable to type 'number'. +tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(11,9): error TS2322: Type 'T & U' is not assignable to type 'number | undefined'. + Type 'string | undefined' is not assignable to type 'number | undefined'. + Type 'string' is not assignable to type 'number | undefined'. + Type 'T & U' is not assignable to type 'number'. +tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12,9): error TS2322: Type 'T & U' is not assignable to type 'null | undefined'. + Type 'string | undefined' is not assignable to type 'null | undefined'. + Type 'string' is not assignable to type 'null | undefined'. + Type 'T & U' is not assignable to type 'null'. + + +==== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts (5 errors) ==== + function f1(x: T & U) { + // Combined constraint of 'T & U' is 'string | number' + let y: string | number = x; + } + + function f2(x: T & U) { + let y1: string | number = x; // Error + ~~ +!!! error TS2322: Type 'T & U' is not assignable to type 'string | number'. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | number'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string | number'. +!!! error TS2322: Type 'T & U' is not assignable to type 'number'. + let y2: string | null = x; // Error + ~~ +!!! error TS2322: Type 'T & U' is not assignable to type 'string | null'. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'string | null'. +!!! error TS2322: Type 'undefined' is not assignable to type 'string | null'. +!!! error TS2322: Type 'T & U' is not assignable to type 'string'. + let y3: string | undefined = x; + let y4: number | null = x; // Error + ~~ +!!! error TS2322: Type 'T & U' is not assignable to type 'number | null'. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | null'. +!!! error TS2322: Type 'undefined' is not assignable to type 'number | null'. +!!! error TS2322: Type 'T & U' is not assignable to type 'number'. + let y5: number | undefined = x; // Error + ~~ +!!! error TS2322: Type 'T & U' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'. +!!! error TS2322: Type 'T & U' is not assignable to type 'number'. + let y6: null | undefined = x; // Error + ~~ +!!! error TS2322: Type 'T & U' is not assignable to type 'null | undefined'. +!!! error TS2322: Type 'string | undefined' is not assignable to type 'null | undefined'. +!!! error TS2322: Type 'string' is not assignable to type 'null | undefined'. +!!! error TS2322: Type 'T & U' is not assignable to type 'null'. + } + + type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined + + // Repro from #23648 + + type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } + + type UnexpectedError = T + type NoErrorHere = T + \ No newline at end of file diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.js b/tests/baselines/reference/intersectionWithUnionConstraint.js new file mode 100644 index 00000000000..6069dbda75c --- /dev/null +++ b/tests/baselines/reference/intersectionWithUnionConstraint.js @@ -0,0 +1,39 @@ +//// [intersectionWithUnionConstraint.ts] +function f1(x: T & U) { + // Combined constraint of 'T & U' is 'string | number' + let y: string | number = x; +} + +function f2(x: T & U) { + let y1: string | number = x; // Error + let y2: string | null = x; // Error + let y3: string | undefined = x; + let y4: number | null = x; // Error + let y5: number | undefined = x; // Error + let y6: null | undefined = x; // Error +} + +type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined + +// Repro from #23648 + +type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } + +type UnexpectedError = T +type NoErrorHere = T + + +//// [intersectionWithUnionConstraint.js] +"use strict"; +function f1(x) { + // Combined constraint of 'T & U' is 'string | number' + var y = x; +} +function f2(x) { + var y1 = x; // Error + var y2 = x; // Error + var y3 = x; + var y4 = x; // Error + var y5 = x; // Error + var y6 = x; // Error +} diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.symbols b/tests/baselines/reference/intersectionWithUnionConstraint.symbols new file mode 100644 index 00000000000..d7ee1e86a22 --- /dev/null +++ b/tests/baselines/reference/intersectionWithUnionConstraint.symbols @@ -0,0 +1,78 @@ +=== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts === +function f1(x: T & U) { +>f1 : Symbol(f1, Decl(intersectionWithUnionConstraint.ts, 0, 0)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 0, 12)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 0, 38)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 0, 66)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 0, 12)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 0, 38)) + + // Combined constraint of 'T & U' is 'string | number' + let y: string | number = x; +>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 2, 7)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 0, 66)) +} + +function f2(x: T & U) { +>f2 : Symbol(f2, Decl(intersectionWithUnionConstraint.ts, 3, 1)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 5, 12)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 5, 50)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 5, 12)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 5, 50)) + + let y1: string | number = x; // Error +>y1 : Symbol(y1, Decl(intersectionWithUnionConstraint.ts, 6, 7)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88)) + + let y2: string | null = x; // Error +>y2 : Symbol(y2, Decl(intersectionWithUnionConstraint.ts, 7, 7)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88)) + + let y3: string | undefined = x; +>y3 : Symbol(y3, Decl(intersectionWithUnionConstraint.ts, 8, 7)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88)) + + let y4: number | null = x; // Error +>y4 : Symbol(y4, Decl(intersectionWithUnionConstraint.ts, 9, 7)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88)) + + let y5: number | undefined = x; // Error +>y5 : Symbol(y5, Decl(intersectionWithUnionConstraint.ts, 10, 7)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88)) + + let y6: null | undefined = x; // Error +>y6 : Symbol(y6, Decl(intersectionWithUnionConstraint.ts, 11, 7)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 5, 88)) +} + +type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined +>T1 : Symbol(T1, Decl(intersectionWithUnionConstraint.ts, 12, 1)) + +// Repro from #23648 + +type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } +>Example : Symbol(Example, Decl(intersectionWithUnionConstraint.ts, 14, 70)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 18, 13)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 18, 15)) +>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 18, 24)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 18, 13)) +>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 18, 24)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 18, 15)) +>UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 18, 96)) +>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 18, 24)) +>NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 20, 47)) +>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 18, 24)) + +type UnexpectedError = T +>UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 18, 96)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 21)) +>PropertyKey : Symbol(PropertyKey, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 21)) + +type NoErrorHere = T +>NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 20, 47)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 21, 17)) +>PropertyKey : Symbol(PropertyKey, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 21, 17)) + diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.types b/tests/baselines/reference/intersectionWithUnionConstraint.types new file mode 100644 index 00000000000..df5fa0f14d3 --- /dev/null +++ b/tests/baselines/reference/intersectionWithUnionConstraint.types @@ -0,0 +1,83 @@ +=== tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts === +function f1(x: T & U) { +>f1 : (x: T & U) => void +>T : T +>U : U +>x : T & U +>T : T +>U : U + + // Combined constraint of 'T & U' is 'string | number' + let y: string | number = x; +>y : string | number +>x : T & U +} + +function f2(x: T & U) { +>f2 : (x: T & U) => void +>T : T +>U : U +>null : null +>x : T & U +>T : T +>U : U + + let y1: string | number = x; // Error +>y1 : string | number +>x : T & U + + let y2: string | null = x; // Error +>y2 : string | null +>null : null +>x : T & U + + let y3: string | undefined = x; +>y3 : string | undefined +>x : T & U + + let y4: number | null = x; // Error +>y4 : number | null +>null : null +>x : T & U + + let y5: number | undefined = x; // Error +>y5 : number | undefined +>x : T & U + + let y6: null | undefined = x; // Error +>y6 : null | undefined +>null : null +>x : T & U +} + +type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined +>T1 : string | undefined +>null : null + +// Repro from #23648 + +type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } +>Example : Example +>T : T +>U : U +>K : K +>T : T +>K : K +>U : U +>UnexpectedError : T +>K : K +>NoErrorHere : T +>K : K + +type UnexpectedError = T +>UnexpectedError : T +>T : T +>PropertyKey : string | number | symbol +>T : T + +type NoErrorHere = T +>NoErrorHere : T +>T : T +>PropertyKey : string | number | symbol +>T : T + From 16c24bd57c5217bb50179879a1b32185cbf8e8a7 Mon Sep 17 00:00:00 2001 From: csigs Date: Wed, 25 Apr 2018 04:10:19 +0000 Subject: [PATCH 188/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5be5577f3a8..ce8b767afab 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -896,6 +896,9 @@ + + + @@ -998,6 +1001,9 @@ + + + @@ -6485,6 +6491,12 @@ + + + + + + From 5280d23b63fb2834f978a170970fd0bfd12c31f2 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 25 Apr 2018 08:04:20 -0700 Subject: [PATCH 189/229] importNameCodeFix: consistently put fixes to use existing imports before fixes for existing imports (#23663) --- src/services/codefixes/importFixes.ts | 42 +++++++++++++------ .../fourslash/importNameCodeFix_order.ts | 21 ++++++++++ 2 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 tests/cases/fourslash/importNameCodeFix_order.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 26fa45d1e53..b8694947472 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -119,6 +119,12 @@ namespace ts.codefix { } function getCodeActionsForImport(exportInfos: ReadonlyArray, context: ImportCodeFixContext): CodeFixAction[] { + const result: CodeFixAction[] = []; + getCodeActionsForImport_separateExistingAndNew(exportInfos, context, result, result); + return result; + } + + function getCodeActionsForImport_separateExistingAndNew(exportInfos: ReadonlyArray, context: ImportCodeFixContext, useExisting: Push, addNew: Push): void { const existingImports = flatMap(exportInfos, info => getImportDeclarations(info, context.checker, context.sourceFile, context.cachedImportDeclarations)); // It is possible that multiple import statements with the same specifier exist in the file. @@ -133,16 +139,18 @@ namespace ts.codefix { // 1. change "member3" to "ns.member3" // 2. add "member3" to the second import statement's import list // and it is up to the user to decide which one fits best. - const useExistingImportActions = !context.symbolToken || !isIdentifier(context.symbolToken) ? emptyArray : mapDefined(existingImports, ({ declaration }) => { - const namespace = getNamespaceImportName(declaration); - if (namespace) { - const moduleSymbol = context.checker.getAliasedSymbol(context.checker.getSymbolAtLocation(namespace)); - if (moduleSymbol && moduleSymbol.exports.has(escapeLeadingUnderscores(context.symbolName))) { - return getCodeActionForUseExistingNamespaceImport(namespace.text, context, context.symbolToken as Identifier); + if (context.symbolToken && isIdentifier(context.symbolToken)) { + for (const { declaration } of existingImports) { + const namespace = getNamespaceImportName(declaration); + if (namespace) { + const moduleSymbol = context.checker.getAliasedSymbol(context.checker.getSymbolAtLocation(namespace)); + if (moduleSymbol && moduleSymbol.exports.has(escapeLeadingUnderscores(context.symbolName))) { + useExisting.push(getCodeActionForUseExistingNamespaceImport(namespace.text, context, context.symbolToken)); + } } } - }); - return [...useExistingImportActions, ...getCodeActionsForAddImport(exportInfos, context, existingImports)]; + } + getCodeActionsForAddImport(exportInfos, context, existingImports, useExisting, addNew); } function getNamespaceImportName(declaration: AnyImportSyntax): Identifier | undefined { @@ -551,7 +559,9 @@ namespace ts.codefix { exportInfos: ReadonlyArray, ctx: ImportCodeFixContext, existingImports: ReadonlyArray, - ): CodeFixAction[] { + useExisting: Push, + addNew: Push, + ): void { const fromExistingImport = firstDefined(existingImports, ({ declaration, importKind }) => { if (declaration.kind === SyntaxKind.ImportDeclaration && declaration.importClause) { const changes = tryUpdateExistingImport(ctx, isImportClause(declaration.importClause) && declaration.importClause || undefined, importKind); @@ -562,14 +572,17 @@ namespace ts.codefix { } }); if (fromExistingImport) { - return [fromExistingImport]; + useExisting.push(fromExistingImport); + return; } const existingDeclaration = firstDefined(existingImports, newImportInfoFromExistingSpecifier); const newImportInfos = existingDeclaration ? [existingDeclaration] : getNewImportInfos(ctx.program, ctx.sourceFile, exportInfos, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host, ctx.preferences); - return newImportInfos.map(info => getCodeActionForNewImport(ctx, info)); + for (const info of newImportInfos) { + addNew.push(getCodeActionForNewImport(ctx, info)); + } } function newImportInfoFromExistingSpecifier({ declaration, importKind }: ExistingImportInfo): NewImportInfo | undefined { @@ -760,7 +773,12 @@ namespace ts.codefix { } }); - return arrayFrom(flatMapIterator(originalSymbolToExportInfos.values(), exportInfos => getCodeActionsForImport(exportInfos, convertToImportCodeFixContext(context, symbolToken, symbolName)))); + const addToExistingDeclaration: CodeFixAction[] = []; + const addNewDeclaration: CodeFixAction[] = []; + originalSymbolToExportInfos.forEach(exportInfos => { + getCodeActionsForImport_separateExistingAndNew(exportInfos, convertToImportCodeFixContext(context, symbolToken, symbolName), addToExistingDeclaration, addNewDeclaration); + }); + return [...addToExistingDeclaration, ...addNewDeclaration]; } function checkSymbolHasMeaning({ declarations }: Symbol, meaning: SemanticMeaning): boolean { diff --git a/tests/cases/fourslash/importNameCodeFix_order.ts b/tests/cases/fourslash/importNameCodeFix_order.ts new file mode 100644 index 00000000000..888b440e928 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_order.ts @@ -0,0 +1,21 @@ +/// + +// @Filename: /a.ts +////export const foo: number; + +// @Filename: /b.ts +////export const foo: number; +////export const bar: number; + +// @Filename: /c.ts +////[|import { bar } from "./b"; +////foo;|] + +goTo.file("/c.ts"); +verify.importFixAtPosition([ +`import { bar, foo } from "./b"; +foo;`, +`import { bar } from "./b"; +import { foo } from "./a"; +foo;`, +]); From 583bcea603f166e559cb94c11452e0f3aee67b2e Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 25 Apr 2018 10:08:35 -0700 Subject: [PATCH 190/229] Always parse an argument for an ElementAccessExpression (#23683) --- src/compiler/diagnosticMessages.json | 4 +++ src/compiler/parser.ts | 17 ++++----- src/compiler/types.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../reference/badArrayIndex.errors.txt | 6 ++-- tests/baselines/reference/badArrayIndex.types | 1 + .../reference/badArraySyntax.errors.txt | 36 +++++++++---------- .../baselines/reference/badArraySyntax.types | 6 ++++ ...annotInvokeNewOnErrorExpression.errors.txt | 6 ++-- .../cannotInvokeNewOnErrorExpression.types | 1 + ...torWithIncompleteTypeAnnotation.errors.txt | 5 ++- ...structorWithIncompleteTypeAnnotation.types | 1 + .../reference/createArray.errors.txt | 24 ++++++------- tests/baselines/reference/createArray.types | 4 +++ .../baselines/reference/libMembers.errors.txt | 6 ++-- tests/baselines/reference/libMembers.types | 1 + .../reference/newOperator.errors.txt | 24 ++++++------- tests/baselines/reference/newOperator.types | 4 +++ .../objectLitArrayDeclNoNew.errors.txt | 5 ++- .../reference/objectLitArrayDeclNoNew.types | 1 + ...rserObjectCreationArrayLiteral1.errors.txt | 6 ++-- .../parserObjectCreationArrayLiteral1.types | 1 + ...rserObjectCreationArrayLiteral3.errors.txt | 6 ++-- .../parserObjectCreationArrayLiteral3.types | 1 + .../reference/parserRealSource10.errors.txt | 30 ++++++++-------- .../reference/parserRealSource10.types | 5 +++ .../reference/parserRealSource11.errors.txt | 23 ++++++------ .../reference/parserRealSource11.types | 3 ++ .../reference/parserRealSource4.errors.txt | 6 ++-- .../reference/parserRealSource4.types | 1 + .../reference/parserRealSource7.errors.txt | 6 ++-- .../reference/parserRealSource7.types | 1 + .../reference/parserRealSource9.errors.txt | 6 ++-- .../reference/parserRealSource9.types | 1 + 35 files changed, 145 insertions(+), 109 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 2c376da7bc9..e81cd4fbc22 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -23,6 +23,10 @@ "category": "Error", "code": 1010 }, + "An element access expression should take an argument.": { + "category": "Error", + "code": 1011 + }, "Unexpected token.": { "category": "Error", "code": 1012 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4cf4c6e4c67..8547eb17114 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1240,7 +1240,7 @@ namespace ts { if (reportAtCurrentPosition) { parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); } - else { + else if (diagnosticMessage) { parseErrorAtCurrentToken(diagnosticMessage, arg0); } @@ -4348,14 +4348,15 @@ namespace ts { const indexedAccess = createNode(SyntaxKind.ElementAccessExpression, expression.pos); indexedAccess.expression = expression; - // It's not uncommon for a user to write: "new Type[]". - // Check for that common pattern and report a better error message. - if (token() !== SyntaxKind.CloseBracketToken) { - indexedAccess.argumentExpression = allowInAnd(parseExpression); - if (indexedAccess.argumentExpression.kind === SyntaxKind.StringLiteral || indexedAccess.argumentExpression.kind === SyntaxKind.NumericLiteral) { - const literal = indexedAccess.argumentExpression; - literal.text = internIdentifier(literal.text); + if (token() === SyntaxKind.CloseBracketToken) { + indexedAccess.argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument); + } + else { + const argument = allowInAnd(parseExpression); + if (isStringOrNumericLiteral(argument)) { + argument.text = internIdentifier(argument.text); } + indexedAccess.argumentExpression = argument; } parseExpected(SyntaxKind.CloseBracketToken); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 06f15e1d77a..1c32168164d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1685,7 +1685,7 @@ namespace ts { export interface ElementAccessExpression extends MemberExpression { kind: SyntaxKind.ElementAccessExpression; expression: LeftHandSideExpression; - argumentExpression?: Expression; + argumentExpression: Expression; } export interface SuperElementAccessExpression extends ElementAccessExpression { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 1f5757ff4ce..8fd42ce26b6 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1019,7 +1019,7 @@ declare namespace ts { interface ElementAccessExpression extends MemberExpression { kind: SyntaxKind.ElementAccessExpression; expression: LeftHandSideExpression; - argumentExpression?: Expression; + argumentExpression: Expression; } interface SuperElementAccessExpression extends ElementAccessExpression { expression: SuperExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3c47002061f..03091849332 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1019,7 +1019,7 @@ declare namespace ts { interface ElementAccessExpression extends MemberExpression { kind: SyntaxKind.ElementAccessExpression; expression: LeftHandSideExpression; - argumentExpression?: Expression; + argumentExpression: Expression; } interface SuperElementAccessExpression extends ElementAccessExpression { expression: SuperExpression; diff --git a/tests/baselines/reference/badArrayIndex.errors.txt b/tests/baselines/reference/badArrayIndex.errors.txt index decfebeeac7..893ac8ee1aa 100644 --- a/tests/baselines/reference/badArrayIndex.errors.txt +++ b/tests/baselines/reference/badArrayIndex.errors.txt @@ -1,10 +1,10 @@ tests/cases/compiler/badArrayIndex.ts(1,15): error TS2693: 'number' only refers to a type, but is being used as a value here. -tests/cases/compiler/badArrayIndex.ts(1,22): error TS1109: Expression expected. +tests/cases/compiler/badArrayIndex.ts(1,22): error TS1011: An element access expression should take an argument. ==== tests/cases/compiler/badArrayIndex.ts (2 errors) ==== var results = number[]; ~~~~~~ !!! error TS2693: 'number' only refers to a type, but is being used as a value here. - ~ -!!! error TS1109: Expression expected. \ No newline at end of file + +!!! error TS1011: An element access expression should take an argument. \ No newline at end of file diff --git a/tests/baselines/reference/badArrayIndex.types b/tests/baselines/reference/badArrayIndex.types index a8b541124b6..05a52242290 100644 --- a/tests/baselines/reference/badArrayIndex.types +++ b/tests/baselines/reference/badArrayIndex.types @@ -3,4 +3,5 @@ var results = number[]; >results : any >number[] : any >number : any +> : any diff --git a/tests/baselines/reference/badArraySyntax.errors.txt b/tests/baselines/reference/badArraySyntax.errors.txt index 3c6b28408f2..428d67703b0 100644 --- a/tests/baselines/reference/badArraySyntax.errors.txt +++ b/tests/baselines/reference/badArraySyntax.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/badArraySyntax.ts(6,15): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. -tests/cases/compiler/badArraySyntax.ts(7,15): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. -tests/cases/compiler/badArraySyntax.ts(8,20): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. -tests/cases/compiler/badArraySyntax.ts(9,20): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. -tests/cases/compiler/badArraySyntax.ts(10,36): error TS1109: Expression expected. -tests/cases/compiler/badArraySyntax.ts(10,40): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/badArraySyntax.ts(6,16): error TS1011: An element access expression should take an argument. +tests/cases/compiler/badArraySyntax.ts(7,16): error TS1011: An element access expression should take an argument. +tests/cases/compiler/badArraySyntax.ts(8,21): error TS1011: An element access expression should take an argument. +tests/cases/compiler/badArraySyntax.ts(9,21): error TS1011: An element access expression should take an argument. +tests/cases/compiler/badArraySyntax.ts(10,30): error TS1011: An element access expression should take an argument. +tests/cases/compiler/badArraySyntax.ts(10,41): error TS1011: An element access expression should take an argument. ==== tests/cases/compiler/badArraySyntax.ts (6 errors) ==== @@ -13,20 +13,20 @@ tests/cases/compiler/badArraySyntax.ts(10,40): error TS1150: 'new T[]' cannot be var a1: Z[] = []; var a2 = new Z[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. var a3 = new Z[](); - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. var a4: Z[] = new Z[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. var a5: Z[] = new Z[](); - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. var a6: Z[][] = new Z [ ] [ ]; - ~ -!!! error TS1109: Expression expected. - ~~~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. + +!!! error TS1011: An element access expression should take an argument. \ No newline at end of file diff --git a/tests/baselines/reference/badArraySyntax.types b/tests/baselines/reference/badArraySyntax.types index f7982034d71..579dc76301f 100644 --- a/tests/baselines/reference/badArraySyntax.types +++ b/tests/baselines/reference/badArraySyntax.types @@ -17,12 +17,14 @@ var a2 = new Z[]; >new Z[] : any >Z[] : any >Z : typeof Z +> : any var a3 = new Z[](); >a3 : any >new Z[]() : any >Z[] : any >Z : typeof Z +> : any var a4: Z[] = new Z[]; >a4 : Z[] @@ -30,6 +32,7 @@ var a4: Z[] = new Z[]; >new Z[] : any >Z[] : any >Z : typeof Z +> : any var a5: Z[] = new Z[](); >a5 : Z[] @@ -37,6 +40,7 @@ var a5: Z[] = new Z[](); >new Z[]() : any >Z[] : any >Z : typeof Z +> : any var a6: Z[][] = new Z [ ] [ ]; >a6 : Z[][] @@ -45,4 +49,6 @@ var a6: Z[][] = new Z [ ] [ ]; >Z [ ] [ ] : any >Z [ ] : any >Z : typeof Z +> : any +> : any diff --git a/tests/baselines/reference/cannotInvokeNewOnErrorExpression.errors.txt b/tests/baselines/reference/cannotInvokeNewOnErrorExpression.errors.txt index fab981a8571..87e02668182 100644 --- a/tests/baselines/reference/cannotInvokeNewOnErrorExpression.errors.txt +++ b/tests/baselines/reference/cannotInvokeNewOnErrorExpression.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/cannotInvokeNewOnErrorExpression.ts(5,15): error TS2339: Property 'ClassA' does not exist on type 'typeof M'. -tests/cases/compiler/cannotInvokeNewOnErrorExpression.ts(5,21): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/cannotInvokeNewOnErrorExpression.ts(5,22): error TS1011: An element access expression should take an argument. ==== tests/cases/compiler/cannotInvokeNewOnErrorExpression.ts (2 errors) ==== @@ -10,5 +10,5 @@ tests/cases/compiler/cannotInvokeNewOnErrorExpression.ts(5,21): error TS1150: 'n var t = new M.ClassA[]; ~~~~~~ !!! error TS2339: Property 'ClassA' does not exist on type 'typeof M'. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. \ No newline at end of file + +!!! error TS1011: An element access expression should take an argument. \ No newline at end of file diff --git a/tests/baselines/reference/cannotInvokeNewOnErrorExpression.types b/tests/baselines/reference/cannotInvokeNewOnErrorExpression.types index 47ccb421623..2b5360feefd 100644 --- a/tests/baselines/reference/cannotInvokeNewOnErrorExpression.types +++ b/tests/baselines/reference/cannotInvokeNewOnErrorExpression.types @@ -12,4 +12,5 @@ var t = new M.ClassA[]; >M.ClassA : any >M : typeof M >ClassA : any +> : any diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt index 1150fe0ff29..a55c3af6555 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt @@ -77,6 +77,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(257,33): error T tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(257,35): error TS2693: 'string' only refers to a type, but is being used as a value here. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(257,43): error TS1109: Expression expected. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(257,52): error TS2693: 'string' only refers to a type, but is being used as a value here. +tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(257,59): error TS1011: An element access expression should take an argument. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(257,60): error TS1005: ';' expected. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(257,65): error TS1109: Expression expected. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(259,9): error TS2304: Cannot find name 'public'. @@ -89,7 +90,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(259,55): error T tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS1128: Declaration or statement expected. -==== tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts (89 errors) ==== +==== tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts (90 errors) ==== declare module "fs" { export class File { constructor(filename: string); @@ -508,6 +509,8 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS !!! error TS1109: Expression expected. ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. + +!!! error TS1011: An element access expression should take an argument. ~ !!! error TS1005: ';' expected. ~ diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.types b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.types index df80419ca16..24f9b2639a8 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.types +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.types @@ -929,6 +929,7 @@ module TypeScriptAllInOne { >rest : any >string[] : any >string : any +> : any >& public : number > : any diff --git a/tests/baselines/reference/createArray.errors.txt b/tests/baselines/reference/createArray.errors.txt index 082e8dc03e2..84f93a727eb 100644 --- a/tests/baselines/reference/createArray.errors.txt +++ b/tests/baselines/reference/createArray.errors.txt @@ -1,35 +1,35 @@ tests/cases/compiler/createArray.ts(1,12): error TS2693: 'number' only refers to a type, but is being used as a value here. -tests/cases/compiler/createArray.ts(1,18): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. -tests/cases/compiler/createArray.ts(6,6): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/createArray.ts(1,19): error TS1011: An element access expression should take an argument. +tests/cases/compiler/createArray.ts(6,7): error TS1011: An element access expression should take an argument. tests/cases/compiler/createArray.ts(7,12): error TS2693: 'boolean' only refers to a type, but is being used as a value here. -tests/cases/compiler/createArray.ts(7,19): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/createArray.ts(7,20): error TS1011: An element access expression should take an argument. tests/cases/compiler/createArray.ts(8,12): error TS2693: 'string' only refers to a type, but is being used as a value here. -tests/cases/compiler/createArray.ts(8,18): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/createArray.ts(8,19): error TS1011: An element access expression should take an argument. ==== tests/cases/compiler/createArray.ts (7 errors) ==== var na=new number[]; ~~~~~~ !!! error TS2693: 'number' only refers to a type, but is being used as a value here. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. class C { } new C[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. var ba=new boolean[]; ~~~~~~~ !!! error TS2693: 'boolean' only refers to a type, but is being used as a value here. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. var sa=new string[]; ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. function f(s:string):number { return 0; } if (ba[14]) { diff --git a/tests/baselines/reference/createArray.types b/tests/baselines/reference/createArray.types index b7c9ada8068..8d140f3e3d8 100644 --- a/tests/baselines/reference/createArray.types +++ b/tests/baselines/reference/createArray.types @@ -4,6 +4,7 @@ var na=new number[]; >new number[] : any >number[] : any >number : any +> : any class C { >C : C @@ -13,18 +14,21 @@ new C[]; >new C[] : any >C[] : any >C : typeof C +> : any var ba=new boolean[]; >ba : any >new boolean[] : any >boolean[] : any >boolean : any +> : any var sa=new string[]; >sa : any >new string[] : any >string[] : any >string : any +> : any function f(s:string):number { return 0; >f : (s: string) => number diff --git a/tests/baselines/reference/libMembers.errors.txt b/tests/baselines/reference/libMembers.errors.txt index 4b025b9a95b..36b65fb62f2 100644 --- a/tests/baselines/reference/libMembers.errors.txt +++ b/tests/baselines/reference/libMembers.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/libMembers.ts(4,3): error TS2339: Property 'subby' does not exist on type 'string'. -tests/cases/compiler/libMembers.ts(9,16): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/libMembers.ts(9,17): error TS1011: An element access expression should take an argument. tests/cases/compiler/libMembers.ts(12,15): error TS2339: Property 'prototype' does not exist on type 'C'. @@ -15,8 +15,8 @@ tests/cases/compiler/libMembers.ts(12,15): error TS2339: Property 'prototype' do export class C { } var a=new C[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. a.length; a.push(new C()); (new C()).prototype; diff --git a/tests/baselines/reference/libMembers.types b/tests/baselines/reference/libMembers.types index a825e822326..351dd02a8f4 100644 --- a/tests/baselines/reference/libMembers.types +++ b/tests/baselines/reference/libMembers.types @@ -43,6 +43,7 @@ module M { >new C[] : any >C[] : any >C : typeof C +> : any a.length; >a.length : any diff --git a/tests/baselines/reference/newOperator.errors.txt b/tests/baselines/reference/newOperator.errors.txt index ae96023a60b..fb98482d85c 100644 --- a/tests/baselines/reference/newOperator.errors.txt +++ b/tests/baselines/reference/newOperator.errors.txt @@ -3,16 +3,15 @@ tests/cases/compiler/newOperator.ts(10,10): error TS2351: Cannot use 'new' with tests/cases/compiler/newOperator.ts(11,10): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. tests/cases/compiler/newOperator.ts(12,5): error TS2693: 'string' only refers to a type, but is being used as a value here. tests/cases/compiler/newOperator.ts(18,14): error TS2693: 'string' only refers to a type, but is being used as a value here. -tests/cases/compiler/newOperator.ts(18,20): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/newOperator.ts(18,21): error TS1011: An element access expression should take an argument. tests/cases/compiler/newOperator.ts(21,1): error TS2693: 'string' only refers to a type, but is being used as a value here. -tests/cases/compiler/newOperator.ts(22,1): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/newOperator.ts(22,2): error TS1011: An element access expression should take an argument. tests/cases/compiler/newOperator.ts(28,13): error TS2304: Cannot find name 'q'. tests/cases/compiler/newOperator.ts(31,10): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -tests/cases/compiler/newOperator.ts(44,16): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. -tests/cases/compiler/newOperator.ts(45,23): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/compiler/newOperator.ts(45,24): error TS1011: An element access expression should take an argument. -==== tests/cases/compiler/newOperator.ts (12 errors) ==== +==== tests/cases/compiler/newOperator.ts (11 errors) ==== interface ifc { } // Attempting to 'new' an interface yields poor error var i = new ifc(); @@ -41,18 +40,17 @@ tests/cases/compiler/newOperator.ts(45,23): error TS1150: 'new T[]' cannot be us var t3 = new string[]( ); ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. var t4 = new string ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. [ - ~ + +!!! error TS1011: An element access expression should take an argument. ] - ~~~~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. ( ); @@ -78,11 +76,9 @@ tests/cases/compiler/newOperator.ts(45,23): error TS1150: 'new T[]' cannot be us class S { public get xs(): M.T[] { - ~~ -!!! error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. return new M.T[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. } } \ No newline at end of file diff --git a/tests/baselines/reference/newOperator.types b/tests/baselines/reference/newOperator.types index 76d52f48294..309235a0f7e 100644 --- a/tests/baselines/reference/newOperator.types +++ b/tests/baselines/reference/newOperator.types @@ -49,6 +49,7 @@ var t3 = new string[]( ); >new string[]( ) : any >string[] : any >string : any +> : any var t4 = >t4 : any @@ -62,6 +63,8 @@ string [ ] +> : any + ( ); @@ -109,6 +112,7 @@ class S { >M.T : typeof M.T >M : typeof M >T : typeof M.T +> : any } } diff --git a/tests/baselines/reference/objectLitArrayDeclNoNew.errors.txt b/tests/baselines/reference/objectLitArrayDeclNoNew.errors.txt index 0c683946550..62b1505dc5b 100644 --- a/tests/baselines/reference/objectLitArrayDeclNoNew.errors.txt +++ b/tests/baselines/reference/objectLitArrayDeclNoNew.errors.txt @@ -1,7 +1,8 @@ +tests/cases/compiler/objectLitArrayDeclNoNew.ts(22,20): error TS1011: An element access expression should take an argument. tests/cases/compiler/objectLitArrayDeclNoNew.ts(27,1): error TS1128: Declaration or statement expected. -==== tests/cases/compiler/objectLitArrayDeclNoNew.ts (1 errors) ==== +==== tests/cases/compiler/objectLitArrayDeclNoNew.ts (2 errors) ==== declare var console; "use strict"; module Test { @@ -24,6 +25,8 @@ tests/cases/compiler/objectLitArrayDeclNoNew.ts(27,1): error TS1128: Declaration var state:IState= null; return { tokens: Gar[],//IToken[], // Missing new. Correct syntax is: tokens: new IToken[] + +!!! error TS1011: An element access expression should take an argument. endState: state }; } diff --git a/tests/baselines/reference/objectLitArrayDeclNoNew.types b/tests/baselines/reference/objectLitArrayDeclNoNew.types index bacd7e09a3c..8ecafcfd367 100644 --- a/tests/baselines/reference/objectLitArrayDeclNoNew.types +++ b/tests/baselines/reference/objectLitArrayDeclNoNew.types @@ -52,6 +52,7 @@ module Test { >tokens : any >Gar[] : any >Gar : typeof Gar +> : any endState: state >endState : IState diff --git a/tests/baselines/reference/parserObjectCreationArrayLiteral1.errors.txt b/tests/baselines/reference/parserObjectCreationArrayLiteral1.errors.txt index 051d2357635..413090769ad 100644 --- a/tests/baselines/reference/parserObjectCreationArrayLiteral1.errors.txt +++ b/tests/baselines/reference/parserObjectCreationArrayLiteral1.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/parser/ecmascript5/parserObjectCreationArrayLiteral1.ts(1,5): error TS2304: Cannot find name 'Foo'. -tests/cases/conformance/parser/ecmascript5/parserObjectCreationArrayLiteral1.ts(1,8): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserObjectCreationArrayLiteral1.ts(1,9): error TS1011: An element access expression should take an argument. ==== tests/cases/conformance/parser/ecmascript5/parserObjectCreationArrayLiteral1.ts (2 errors) ==== new Foo[]; ~~~ !!! error TS2304: Cannot find name 'Foo'. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. \ No newline at end of file + +!!! error TS1011: An element access expression should take an argument. \ No newline at end of file diff --git a/tests/baselines/reference/parserObjectCreationArrayLiteral1.types b/tests/baselines/reference/parserObjectCreationArrayLiteral1.types index 37a7fa0fa11..a44cf719566 100644 --- a/tests/baselines/reference/parserObjectCreationArrayLiteral1.types +++ b/tests/baselines/reference/parserObjectCreationArrayLiteral1.types @@ -3,4 +3,5 @@ new Foo[]; >new Foo[] : any >Foo[] : any >Foo : any +> : any diff --git a/tests/baselines/reference/parserObjectCreationArrayLiteral3.errors.txt b/tests/baselines/reference/parserObjectCreationArrayLiteral3.errors.txt index b7d18f471da..690558164ee 100644 --- a/tests/baselines/reference/parserObjectCreationArrayLiteral3.errors.txt +++ b/tests/baselines/reference/parserObjectCreationArrayLiteral3.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/parser/ecmascript5/parserObjectCreationArrayLiteral3.ts(1,5): error TS2304: Cannot find name 'Foo'. -tests/cases/conformance/parser/ecmascript5/parserObjectCreationArrayLiteral3.ts(1,8): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserObjectCreationArrayLiteral3.ts(1,9): error TS1011: An element access expression should take an argument. ==== tests/cases/conformance/parser/ecmascript5/parserObjectCreationArrayLiteral3.ts (2 errors) ==== new Foo[](); ~~~ !!! error TS2304: Cannot find name 'Foo'. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. \ No newline at end of file + +!!! error TS1011: An element access expression should take an argument. \ No newline at end of file diff --git a/tests/baselines/reference/parserObjectCreationArrayLiteral3.types b/tests/baselines/reference/parserObjectCreationArrayLiteral3.types index c44eea0c755..0a7eb3bb820 100644 --- a/tests/baselines/reference/parserObjectCreationArrayLiteral3.types +++ b/tests/baselines/reference/parserObjectCreationArrayLiteral3.types @@ -3,4 +3,5 @@ new Foo[](); >new Foo[]() : any >Foo[] : any >Foo : any +> : any diff --git a/tests/baselines/reference/parserRealSource10.errors.txt b/tests/baselines/reference/parserRealSource10.errors.txt index 6fd27b8351e..d53ef3c16f9 100644 --- a/tests/baselines/reference/parserRealSource10.errors.txt +++ b/tests/baselines/reference/parserRealSource10.errors.txt @@ -1,12 +1,12 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(4,21): error TS6053: File 'tests/cases/conformance/parser/ecmascript5/typescript.ts' not found. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(127,33): error TS2449: Class 'TokenInfo' used before its declaration. -tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(127,42): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(127,43): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(128,36): error TS2693: 'string' only refers to a type, but is being used as a value here. -tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(128,42): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(128,43): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(129,41): error TS2693: 'number' only refers to a type, but is being used as a value here. -tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(129,47): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(129,48): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(130,35): error TS2693: 'boolean' only refers to a type, but is being used as a value here. -tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(130,42): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(130,43): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(179,54): error TS2304: Cannot find name 'ErrorRecoverySet'. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(184,28): error TS2304: Cannot find name 'ErrorRecoverySet'. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(188,34): error TS2304: Cannot find name 'NodeType'. @@ -340,7 +340,7 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(312,128): error tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(312,149): error TS2304: Cannot find name 'ErrorRecoverySet'. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(355,52): error TS2304: Cannot find name 'NodeType'. tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(356,53): error TS2304: Cannot find name 'NodeType'. -tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(449,40): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(449,41): error TS1011: An element access expression should take an argument. ==== tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts (343 errors) ==== @@ -475,23 +475,23 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(449,40): error export var tokenTable = new TokenInfo[]; ~~~~~~~~~ !!! error TS2449: Class 'TokenInfo' used before its declaration. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. export var nodeTypeTable = new string[]; ~~~~~~ !!! error TS2693: 'string' only refers to a type, but is being used as a value here. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. export var nodeTypeToTokTable = new number[]; ~~~~~~ !!! error TS2693: 'number' only refers to a type, but is being used as a value here. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. export var noRegexTable = new boolean[]; ~~~~~~~ !!! error TS2693: 'boolean' only refers to a type, but is being used as a value here. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. noRegexTable[TokenID.Identifier] = true; noRegexTable[TokenID.StringLiteral] = true; @@ -1477,8 +1477,8 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource10.ts(449,40): error // TODO: new with length TokenID.LimFixed export var staticTokens = new Token[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. export function initializeStaticTokens() { for (var i = 0; i <= TokenID.LimFixed; i++) { staticTokens[i] = new Token(i); diff --git a/tests/baselines/reference/parserRealSource10.types b/tests/baselines/reference/parserRealSource10.types index 90773019475..9962a763c72 100644 --- a/tests/baselines/reference/parserRealSource10.types +++ b/tests/baselines/reference/parserRealSource10.types @@ -365,24 +365,28 @@ module TypeScript { >new TokenInfo[] : any >TokenInfo[] : any >TokenInfo : typeof TokenInfo +> : any export var nodeTypeTable = new string[]; >nodeTypeTable : any >new string[] : any >string[] : any >string : any +> : any export var nodeTypeToTokTable = new number[]; >nodeTypeToTokTable : any >new number[] : any >number[] : any >number : any +> : any export var noRegexTable = new boolean[]; >noRegexTable : any >new boolean[] : any >boolean[] : any >boolean : any +> : any noRegexTable[TokenID.Identifier] = true; >noRegexTable[TokenID.Identifier] = true : true @@ -3949,6 +3953,7 @@ module TypeScript { >new Token[] : any >Token[] : any >Token : typeof Token +> : any export function initializeStaticTokens() { >initializeStaticTokens : () => void diff --git a/tests/baselines/reference/parserRealSource11.errors.txt b/tests/baselines/reference/parserRealSource11.errors.txt index 598b447d965..0b676969a02 100644 --- a/tests/baselines/reference/parserRealSource11.errors.txt +++ b/tests/baselines/reference/parserRealSource11.errors.txt @@ -40,7 +40,7 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(151,57): error tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(155,26): error TS2304: Cannot find name 'NodeType'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(184,19): error TS2304: Cannot find name 'NodeType'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(192,32): error TS2304: Cannot find name 'SymbolScope'. -tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(193,40): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(193,41): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(196,19): error TS2304: Cannot find name 'NodeType'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(199,42): error TS2304: Cannot find name 'ControlFlowContext'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(219,33): error TS2304: Cannot find name 'NodeType'. @@ -215,7 +215,6 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(838,24): error tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(841,61): error TS2304: Cannot find name 'TypeSymbol'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(850,52): error TS2304: Cannot find name 'TokenID'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(863,36): error TS2304: Cannot find name 'TypeFlow'. -tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(867,29): error TS1015: Parameter cannot have question mark and initializer. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(868,38): error TS2304: Cannot find name 'NodeType'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(877,40): error TS2304: Cannot find name 'NodeType'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(891,27): error TS2304: Cannot find name 'VarFlags'. @@ -252,9 +251,9 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1004,44): error tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1004,67): error TS2304: Cannot find name 'FncFlags'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1005,57): error TS2304: Cannot find name 'FncFlags'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1007,47): error TS2304: Cannot find name 'Symbol'. -tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1009,45): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1009,46): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1022,32): error TS2304: Cannot find name 'Symbol'. -tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1024,47): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1024,48): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1032,36): error TS2304: Cannot find name 'ControlFlowContext'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1033,29): error TS2304: Cannot find name 'BasicBlock'. tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(1034,28): error TS2304: Cannot find name 'BasicBlock'. @@ -517,7 +516,7 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(2356,30): error tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(2356,48): error TS2304: Cannot find name 'TokenID'. -==== tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts (517 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts (516 errors) ==== // Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. // See LICENSE.txt in the project root for complete license information. @@ -795,8 +794,8 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(2356,48): error ~~~~~~~~~~~ !!! error TS2304: Cannot find name 'SymbolScope'. public members: AST[] = new AST[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. constructor () { super(NodeType.List); @@ -1819,8 +1818,6 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(2356,48): error } public getAliasName(aliasAST?: AST = this.alias) : string { - ~~~~~~~~ -!!! error TS1015: Parameter cannot have question mark and initializer. if (aliasAST.nodeType == NodeType.Name) { ~~~~~~~~ !!! error TS2304: Cannot find name 'NodeType'. @@ -2035,8 +2032,8 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(2356,48): error !!! error TS2304: Cannot find name 'Symbol'. if (this.envids == null) { this.envids = new Identifier[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. } this.envids[this.envids.length] = id; var outerFnc = this.enclosingFnc; @@ -2054,8 +2051,8 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource11.ts(2356,48): error !!! error TS2304: Cannot find name 'Symbol'. if (this.jumpRefs == null) { this.jumpRefs = new Identifier[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. } var id = new Identifier(sym.name); this.jumpRefs[this.jumpRefs.length] = id; diff --git a/tests/baselines/reference/parserRealSource11.types b/tests/baselines/reference/parserRealSource11.types index 389db34d7c6..389292c7f03 100644 --- a/tests/baselines/reference/parserRealSource11.types +++ b/tests/baselines/reference/parserRealSource11.types @@ -853,6 +853,7 @@ module TypeScript { >new AST[] : any >AST[] : any >AST : typeof AST +> : any constructor () { super(NodeType.List); @@ -4642,6 +4643,7 @@ module TypeScript { >new Identifier[] : any >Identifier[] : any >Identifier : typeof Identifier +> : any } this.envids[this.envids.length] = id; >this.envids[this.envids.length] = id : Identifier @@ -4724,6 +4726,7 @@ module TypeScript { >new Identifier[] : any >Identifier[] : any >Identifier : typeof Identifier +> : any } var id = new Identifier(sym.name); >id : Identifier diff --git a/tests/baselines/reference/parserRealSource4.errors.txt b/tests/baselines/reference/parserRealSource4.errors.txt index 5fe47b7a8e3..ed703c60c20 100644 --- a/tests/baselines/reference/parserRealSource4.errors.txt +++ b/tests/baselines/reference/parserRealSource4.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource4.ts(4,21): error TS6053: File 'tests/cases/conformance/parser/ecmascript5/typescript.ts' not found. -tests/cases/conformance/parser/ecmascript5/parserRealSource4.ts(195,37): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource4.ts(195,38): error TS1011: An element access expression should take an argument. ==== tests/cases/conformance/parser/ecmascript5/parserRealSource4.ts (2 errors) ==== @@ -200,8 +200,8 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource4.ts(195,37): error T export class HashTable { public itemCount: number = 0; public table = new HashEntry[]; - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. constructor (public size: number, public hashFn: (key) =>number, public equalsFn: (key1, key2) =>boolean) { diff --git a/tests/baselines/reference/parserRealSource4.types b/tests/baselines/reference/parserRealSource4.types index 175ea23db81..ed0d23feb41 100644 --- a/tests/baselines/reference/parserRealSource4.types +++ b/tests/baselines/reference/parserRealSource4.types @@ -748,6 +748,7 @@ module TypeScript { >new HashEntry[] : any >HashEntry[] : any >HashEntry : typeof HashEntry +> : any constructor (public size: number, public hashFn: (key) =>number, >size : number diff --git a/tests/baselines/reference/parserRealSource7.errors.txt b/tests/baselines/reference/parserRealSource7.errors.txt index 7d9627d4823..4afc02b71aa 100644 --- a/tests/baselines/reference/parserRealSource7.errors.txt +++ b/tests/baselines/reference/parserRealSource7.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(4,21): error TS6 tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(12,38): error TS2304: Cannot find name 'ASTList'. tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(12,62): error TS2304: Cannot find name 'TypeLink'. tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(16,37): error TS2552: Cannot find name 'TypeLink'. Did you mean 'typeLink'? -tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(16,45): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(16,46): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(21,36): error TS2552: Cannot find name 'TypeLink'. Did you mean 'typeLink'? tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(29,29): error TS2304: Cannot find name 'Type'. tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(29,45): error TS2304: Cannot find name 'TypeDeclaration'. @@ -328,8 +328,8 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource7.ts(828,13): error T baseTypeLinks = new TypeLink[]; ~~~~~~~~ !!! error TS2552: Cannot find name 'TypeLink'. Did you mean 'typeLink'? - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. } for (var i = 0; i < len; i++) { var baseExpr = bases.members[i]; diff --git a/tests/baselines/reference/parserRealSource7.types b/tests/baselines/reference/parserRealSource7.types index 6a52d684573..838b2576d24 100644 --- a/tests/baselines/reference/parserRealSource7.types +++ b/tests/baselines/reference/parserRealSource7.types @@ -48,6 +48,7 @@ module TypeScript { >new TypeLink[] : any >TypeLink[] : any >TypeLink : any +> : any } for (var i = 0; i < len; i++) { >i : number diff --git a/tests/baselines/reference/parserRealSource9.errors.txt b/tests/baselines/reference/parserRealSource9.errors.txt index 6533fdbcfc4..0d918c7878c 100644 --- a/tests/baselines/reference/parserRealSource9.errors.txt +++ b/tests/baselines/reference/parserRealSource9.errors.txt @@ -4,7 +4,7 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(9,48): error TS2 tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(9,67): error TS2304: Cannot find name 'SymbolScope'. tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(10,30): error TS2304: Cannot find name 'Type'. tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(12,35): error TS2304: Cannot find name 'Type'. -tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(12,39): error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. +tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(12,40): error TS1011: An element access expression should take an argument. tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(29,36): error TS2304: Cannot find name 'SymbolScope'. tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(29,55): error TS2304: Cannot find name 'Type'. tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(67,54): error TS2304: Cannot find name 'SignatureGroup'. @@ -58,8 +58,8 @@ tests/cases/conformance/parser/ecmascript5/parserRealSource9.ts(200,48): error T extendsList = new Type[]; ~~~~ !!! error TS2304: Cannot find name 'Type'. - ~~ -!!! error TS1150: 'new T[]' cannot be used to create an array. Use 'new Array()' instead. + +!!! error TS1011: An element access expression should take an argument. for (var i = 0, len = typeLinks.length; i < len; i++) { var typeLink = typeLinks[i]; this.checker.resolvingBases = true; diff --git a/tests/baselines/reference/parserRealSource9.types b/tests/baselines/reference/parserRealSource9.types index 7293d9f3d26..17a8591b3ec 100644 --- a/tests/baselines/reference/parserRealSource9.types +++ b/tests/baselines/reference/parserRealSource9.types @@ -35,6 +35,7 @@ module TypeScript { >new Type[] : any >Type[] : any >Type : any +> : any for (var i = 0, len = typeLinks.length; i < len; i++) { >i : number From 3707f7dfbe56e408ee61fedc733c9bc35cfe2644 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 25 Apr 2018 10:58:08 -0700 Subject: [PATCH 191/229] Handle more situations involving combined constraints of intersections --- src/compiler/checker.ts | 85 ++++++++++++++++++++++++++--------------- src/compiler/types.ts | 2 + 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0618abe75bb..64669cda10e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6428,22 +6428,43 @@ namespace ts { return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type); } - function getUnionConstraintOfIntersection(type: IntersectionType) { + function getUnionConstraintOfIntersection(type: IntersectionType, targetIsUnion: boolean) { let constraints: Type[]; + let hasDisjointDomainType = false; for (const t of type.types) { if (t.flags & TypeFlags.Instantiable) { - const baseConstraint = getBaseConstraintOfType(t); - if (!(baseConstraint.flags & TypeFlags.Union)) { - return undefined; + // We keep following constraints as long as we have an instantiable type that is known + // not to be circular or infinite (hence we stop on index access types). + let constraint = getConstraintOfType(t); + while (constraint && constraint.flags & (TypeFlags.TypeParameter | TypeFlags.Index | TypeFlags.Conditional)) { + constraint = getConstraintOfType(constraint); } - constraints = append(constraints, baseConstraint); + if (constraint) { + // A constraint that isn't a union type implies that the final type would be a non-union + // type as well. Since non-union constraints are of no interest, we can exit here. + if (!(constraint.flags & TypeFlags.Union)) { + return undefined; + } + constraints = append(constraints, constraint); + } + } + else if (t.flags & TypeFlags.DisjointDomains) { + hasDisjointDomainType = true; } } - if (constraints) { - const constraint = getIntersectionType(constraints); - if (constraint.flags & TypeFlags.Union) { - return constraint; + // If the target is a union type or if we are intersecting with types belonging to one of the + // disjoint domans, we may end up producing a constraint that hasn't been examined before. + if (constraints && (targetIsUnion || hasDisjointDomainType)) { + if (hasDisjointDomainType) { + // We add any types belong to one of the disjoint domans because they might cause the final + // intersection operation to reduce the union constraints. + for (const t of type.types) { + if (t.flags & TypeFlags.DisjointDomains) { + constraints = append(constraints, t); + } + } } + return getIntersectionType(constraints); } return undefined; } @@ -7920,10 +7941,11 @@ namespace ts { // Return true if the given intersection type contains // more than one unit type or, // an object type and a nullable type (null or undefined), or - // a string-like type and a non-string-like primitive type, or - // a number-like type and a non-number-like primitive type, or - // a symbol-like type and a non-symbol-like primitive type, or - // a void-like type and a non-void-like primitive type. + // a string-like type and a type known to be non-string-like, or + // a number-like type and a type known to be non-number-like, or + // a symbol-like type and a type known to be non-symbol-like, or + // a void-like type and a type known to be non-void-like, or + // a non-primitive type and a type known to be primitive. function isEmptyIntersectionType(type: IntersectionType) { let combined: TypeFlags = 0; for (const t of type.types) { @@ -7932,10 +7954,11 @@ namespace ts { } combined |= t.flags; if (combined & TypeFlags.Nullable && combined & (TypeFlags.Object | TypeFlags.NonPrimitive) || - combined & TypeFlags.StringLike && combined & (TypeFlags.Primitive & ~TypeFlags.StringLike) || - combined & TypeFlags.NumberLike && combined & (TypeFlags.Primitive & ~TypeFlags.NumberLike) || - combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.Primitive & ~TypeFlags.ESSymbolLike) || - combined & TypeFlags.VoidLike && combined & (TypeFlags.Primitive & ~TypeFlags.VoidLike)) { + combined & TypeFlags.NonPrimitive && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NonPrimitive) || + combined & TypeFlags.StringLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.StringLike) || + combined & TypeFlags.NumberLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.NumberLike) || + combined & TypeFlags.ESSymbolLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.ESSymbolLike) || + combined & TypeFlags.VoidLike && combined & (TypeFlags.DisjointDomains & ~TypeFlags.VoidLike)) { return true; } } @@ -10154,19 +10177,21 @@ namespace ts { errorInfo = saveErrorInfo; } } - if (!result && source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Union) { - // The combined constraint of an intersection type is the intersection of the constraints of - // the constituents. Since we break down union types before intersection types, if the target - // type is a union type and the source type is an intersection type with a combined constraint - // that is a union type, we need an extra check to see if the combined constraint is related to - // the target. For example, given two type variables T and U, each with the constraint - // 'string | number', the combined constraint of 'T & U' is 'string | number' and we need to - // check this constraint against the union on the target side. - const constraint = getUnionConstraintOfIntersection(source); - if (constraint) { - if (result = isRelatedTo(constraint, target, reportErrors)) { - errorInfo = saveErrorInfo; - } + } + if (!result && source.flags & TypeFlags.Intersection) { + // The combined constraint of an intersection type is the intersection of the constraints of + // the constituents. When an intersection type contains instantiable types with union type + // constraints, there are situations where we need to examine the combined constraint. One is + // when the target is a union type. Another is when the intersection contains types belonging + // to one of the disjoint domains. For example, given type variables T and U, each with the + // constraint 'string | number', the combined constraint of 'T & U' is 'string | number' and + // we need to check this constraint against a union on the target side. Also, given a type + // variable V constrained to 'string | number', 'V & number' has a combined constraint of + // 'string & number | number & number' which reduces to just 'number'. + const constraint = getUnionConstraintOfIntersection(source, !!(target.flags & TypeFlags.Union)); + if (constraint) { + if (result = isRelatedTo(constraint, target, reportErrors)) { + errorInfo = saveErrorInfo; } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index fd3a58bc5ea..06491357e51 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3614,6 +3614,8 @@ namespace ts { EnumLike = Enum | EnumLiteral, ESSymbolLike = ESSymbol | UniqueESSymbol, VoidLike = Void | Undefined, + /* @internal */ + DisjointDomains = NonPrimitive | StringLike | NumberLike | BooleanLike | ESSymbolLike | VoidLike | Null, UnionOrIntersection = Union | Intersection, StructuredType = Object | Union | Intersection, TypeVariable = TypeParameter | IndexedAccess, From 8a7c2031fd76239b0e6f661d09210febb8dd9ef3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 25 Apr 2018 10:58:20 -0700 Subject: [PATCH 192/229] Accept new baselines --- .../reference/keyofAndIndexedAccessErrors.errors.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index bbd4685a492..c74c90c510f 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -44,6 +44,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(87,5): error tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(103,9): error TS2322: Type 'Extract' is not assignable to type 'K'. Type 'string & keyof T' is not assignable to type 'K'. Type 'string' is not assignable to type 'K'. + Type 'string' is not assignable to type 'K'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(105,9): error TS2322: Type 'T[Extract]' is not assignable to type 'T[K]'. Type 'Extract' is not assignable to type 'K'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(108,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. @@ -55,6 +56,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(114,5): error Type 'Extract' is not assignable to type 'J'. Type 'string & keyof T' is not assignable to type 'J'. Type 'string' is not assignable to type 'J'. + Type 'string' is not assignable to type 'J'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'. Type 'T' is not assignable to type 'U'. @@ -238,6 +240,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error !!! error TS2322: Type 'Extract' is not assignable to type 'K'. !!! error TS2322: Type 'string & keyof T' is not assignable to type 'K'. !!! error TS2322: Type 'string' is not assignable to type 'K'. +!!! error TS2322: Type 'string' is not assignable to type 'K'. t[key] = tk; // ok, T[K] ==> T[keyof T] tk = t[key]; // error, T[keyof T] =/=> T[K] ~~ @@ -264,6 +267,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(117,5): error !!! error TS2322: Type 'Extract' is not assignable to type 'J'. !!! error TS2322: Type 'string & keyof T' is not assignable to type 'J'. !!! error TS2322: Type 'string' is not assignable to type 'J'. +!!! error TS2322: Type 'string' is not assignable to type 'J'. tk = uj; uj = tk; // error From 8442a45bb6cd9f016dcd5aba0a17a10e38660de7 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 25 Apr 2018 11:03:25 -0700 Subject: [PATCH 193/229] Add additional tests --- .../intersection/intersectionWithUnionConstraint.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts b/tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts index b406dd91586..278d72595cd 100644 --- a/tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts +++ b/tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts @@ -16,6 +16,18 @@ function f2(x: T & (number | object | undefined)) { + const y: number | undefined = x; +} + +function f4(x: T & (number | object)) { + const y: number = x; +} + +function f5(x: keyof T & U) { + let y: keyof any = x; +} + // Repro from #23648 type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } From bbcb1bb25a6e74f956e8819a84fcf9ce3c897e79 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 25 Apr 2018 11:03:39 -0700 Subject: [PATCH 194/229] Accept new baselines --- ...intersectionWithUnionConstraint.errors.txt | 12 ++++ .../intersectionWithUnionConstraint.js | 21 ++++++ .../intersectionWithUnionConstraint.symbols | 70 ++++++++++++++----- .../intersectionWithUnionConstraint.types | 36 ++++++++++ 4 files changed, 122 insertions(+), 17 deletions(-) diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt b/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt index 8892e412805..9bdfc6f30f9 100644 --- a/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt +++ b/tests/baselines/reference/intersectionWithUnionConstraint.errors.txt @@ -62,6 +62,18 @@ tests/cases/conformance/types/intersection/intersectionWithUnionConstraint.ts(12 type T1 = (string | number | undefined) & (string | null | undefined); // string | undefined + function f3(x: T & (number | object | undefined)) { + const y: number | undefined = x; + } + + function f4(x: T & (number | object)) { + const y: number = x; + } + + function f5(x: keyof T & U) { + let y: keyof any = x; + } + // Repro from #23648 type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.js b/tests/baselines/reference/intersectionWithUnionConstraint.js index 6069dbda75c..fc3e50309c6 100644 --- a/tests/baselines/reference/intersectionWithUnionConstraint.js +++ b/tests/baselines/reference/intersectionWithUnionConstraint.js @@ -15,6 +15,18 @@ function f2(x: T & (number | object | undefined)) { + const y: number | undefined = x; +} + +function f4(x: T & (number | object)) { + const y: number = x; +} + +function f5(x: keyof T & U) { + let y: keyof any = x; +} + // Repro from #23648 type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } @@ -37,3 +49,12 @@ function f2(x) { var y5 = x; // Error var y6 = x; // Error } +function f3(x) { + var y = x; +} +function f4(x) { + var y = x; +} +function f5(x) { + var y = x; +} diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.symbols b/tests/baselines/reference/intersectionWithUnionConstraint.symbols index d7ee1e86a22..0b7d7455977 100644 --- a/tests/baselines/reference/intersectionWithUnionConstraint.symbols +++ b/tests/baselines/reference/intersectionWithUnionConstraint.symbols @@ -49,30 +49,66 @@ function f2T1 : Symbol(T1, Decl(intersectionWithUnionConstraint.ts, 12, 1)) +function f3(x: T & (number | object | undefined)) { +>f3 : Symbol(f3, Decl(intersectionWithUnionConstraint.ts, 14, 70)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 16, 12)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 16, 51)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 16, 12)) + + const y: number | undefined = x; +>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 17, 9)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 16, 51)) +} + +function f4(x: T & (number | object)) { +>f4 : Symbol(f4, Decl(intersectionWithUnionConstraint.ts, 18, 1)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 12)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 20, 39)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 12)) + + const y: number = x; +>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 21, 9)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 20, 39)) +} + +function f5(x: keyof T & U) { +>f5 : Symbol(f5, Decl(intersectionWithUnionConstraint.ts, 22, 1)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 24, 14)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 24, 34)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 24, 12)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 24, 14)) + + let y: keyof any = x; +>y : Symbol(y, Decl(intersectionWithUnionConstraint.ts, 25, 7)) +>x : Symbol(x, Decl(intersectionWithUnionConstraint.ts, 24, 34)) +} + // Repro from #23648 type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } ->Example : Symbol(Example, Decl(intersectionWithUnionConstraint.ts, 14, 70)) ->T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 18, 13)) ->U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 18, 15)) ->K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 18, 24)) ->T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 18, 13)) ->K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 18, 24)) ->U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 18, 15)) ->UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 18, 96)) ->K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 18, 24)) ->NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 20, 47)) ->K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 18, 24)) +>Example : Symbol(Example, Decl(intersectionWithUnionConstraint.ts, 26, 1)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 30, 13)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 30, 15)) +>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 30, 13)) +>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24)) +>U : Symbol(U, Decl(intersectionWithUnionConstraint.ts, 30, 15)) +>UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 30, 96)) +>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24)) +>NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 32, 47)) +>K : Symbol(K, Decl(intersectionWithUnionConstraint.ts, 30, 24)) type UnexpectedError = T ->UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 18, 96)) ->T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 21)) +>UnexpectedError : Symbol(UnexpectedError, Decl(intersectionWithUnionConstraint.ts, 30, 96)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 32, 21)) >PropertyKey : Symbol(PropertyKey, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 20, 21)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 32, 21)) type NoErrorHere = T ->NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 20, 47)) ->T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 21, 17)) +>NoErrorHere : Symbol(NoErrorHere, Decl(intersectionWithUnionConstraint.ts, 32, 47)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 33, 17)) >PropertyKey : Symbol(PropertyKey, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 21, 17)) +>T : Symbol(T, Decl(intersectionWithUnionConstraint.ts, 33, 17)) diff --git a/tests/baselines/reference/intersectionWithUnionConstraint.types b/tests/baselines/reference/intersectionWithUnionConstraint.types index df5fa0f14d3..bef278feba1 100644 --- a/tests/baselines/reference/intersectionWithUnionConstraint.types +++ b/tests/baselines/reference/intersectionWithUnionConstraint.types @@ -54,6 +54,42 @@ type T1 = (string | number | undefined) & (string | null | undefined); // strin >T1 : string | undefined >null : null +function f3(x: T & (number | object | undefined)) { +>f3 : (x: (T & undefined) | (T & number) | (T & object)) => void +>T : T +>x : (T & undefined) | (T & number) | (T & object) +>T : T + + const y: number | undefined = x; +>y : number | undefined +>x : (T & undefined) | (T & number) | (T & object) +} + +function f4(x: T & (number | object)) { +>f4 : (x: (T & number) | (T & object)) => void +>T : T +>x : (T & number) | (T & object) +>T : T + + const y: number = x; +>y : number +>x : (T & number) | (T & object) +} + +function f5(x: keyof T & U) { +>f5 : (x: keyof T & U) => void +>T : T +>U : U +>T : T +>x : keyof T & U +>T : T +>U : U + + let y: keyof any = x; +>y : string | number | symbol +>x : keyof T & U +} + // Repro from #23648 type Example = { [K in keyof T]: K extends keyof U ? UnexpectedError : NoErrorHere } From ec05f29632b7d364b9d768ce958a3fcbc500d10b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 25 Apr 2018 11:44:13 -0700 Subject: [PATCH 195/229] Make signature help node building cancellable (#23543) * Make token building cancellable * Scope cancellation token, make find all refs and quickinfo cancellable * Make completion entry details cancellable * Actually accept public API update * Add test verifying cancellations within checker for select language service operations * Document runWithCancellationToken a bit more * Add post-cancellation verification to test --- src/compiler/checker.ts | 13 +++ src/compiler/types.ts | 7 ++ .../cancellableLanguageServiceOperations.ts | 95 +++++++++++++++++++ src/services/completions.ts | 16 ++-- src/services/findAllReferences.ts | 5 +- src/services/services.ts | 10 +- src/services/signatureHelp.ts | 8 +- .../reference/api/tsserverlibrary.d.ts | 6 ++ tests/baselines/reference/api/typescript.d.ts | 6 ++ 9 files changed, 152 insertions(+), 14 deletions(-) create mode 100644 src/harness/unittests/cancellableLanguageServiceOperations.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 00ddb416e22..f3be433aec1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -325,6 +325,16 @@ namespace ts { return diagnostics; } }, + + runWithCancellationToken: (token, callback) => { + try { + cancellationToken = token; + return callback(checker); + } + finally { + cancellationToken = undefined; + } + } }; const tupleTypes: GenericType[] = []; @@ -2988,6 +2998,9 @@ namespace ts { } function typeToTypeNodeHelper(type: Type, context: NodeBuilderContext): TypeNode { + if (cancellationToken && cancellationToken.throwIfCancellationRequested) { + cancellationToken.throwIfCancellationRequested(); + } const inTypeAlias = context.flags & NodeBuilderFlags.InTypeAlias; context.flags &= ~NodeBuilderFlags.InTypeAlias; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1c32168164d..2aea2e29742 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3000,6 +3000,13 @@ namespace ts { * Others are added in computeSuggestionDiagnostics. */ /* @internal */ getSuggestionDiagnostics(file: SourceFile): ReadonlyArray; + + /** + * Depending on the operation performed, it may be appropriate to throw away the checker + * if the cancellation token is triggered. Typically, if it is used for error checking + * and the operation is cancelled, then it should be discarded, otherwise it is safe to keep. + */ + runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) => T): T; } /* @internal */ diff --git a/src/harness/unittests/cancellableLanguageServiceOperations.ts b/src/harness/unittests/cancellableLanguageServiceOperations.ts new file mode 100644 index 00000000000..7ae85ce2cba --- /dev/null +++ b/src/harness/unittests/cancellableLanguageServiceOperations.ts @@ -0,0 +1,95 @@ +/// + +namespace ts { + describe("cancellableLanguageServiceOperations", () => { + const file = ` + function foo(): void; + function foo(x: T): T; + function foo(x?: T): T | void {} + foo(f); + `; + it("can cancel signature help mid-request", () => { + verifyOperationCancelledAfter(file, 4, service => // Two calls are top-level in services, one is the root type, and the second should be for the parameter type + service.getSignatureHelpItems("file.ts", file.lastIndexOf("f")), + r => assert.exists(r.items[0]) + ); + }); + + it("can cancel find all references mid-request", () => { + verifyOperationCancelledAfter(file, 3, service => // Two calls are top-level in services, one is the root type + service.findReferences("file.ts", file.lastIndexOf("o")), + r => assert.exists(r[0].definition) + ); + }); + + it("can cancel quick info mid-request", () => { + verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for quickinfo, so the first check is within the checker + service.getQuickInfoAtPosition("file.ts", file.lastIndexOf("o")), + r => assert.exists(r.displayParts) + ); + }); + + it("can cancel completion entry details mid-request", () => { + const options: FormatCodeSettings = { + indentSize: 4, + tabSize: 4, + newLineCharacter: "\n", + convertTabsToSpaces: true, + indentStyle: IndentStyle.Smart, + insertSpaceAfterConstructor: false, + insertSpaceAfterCommaDelimiter: true, + insertSpaceAfterSemicolonInForStatements: true, + insertSpaceBeforeAndAfterBinaryOperators: true, + insertSpaceAfterKeywordsInControlFlowStatements: true, + insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, + insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, + insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, + insertSpaceBeforeFunctionParenthesis: false, + placeOpenBraceOnNewLineForFunctions: false, + placeOpenBraceOnNewLineForControlBlocks: false, + }; + verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for completion entry details, so the first check is within the checker + service.getCompletionEntryDetails("file.ts", file.lastIndexOf("f"), "foo", options, /*content*/ undefined, {}), + r => assert.exists(r.displayParts) + ); + }); + }); + + function verifyOperationCancelledAfter(content: string, cancelAfter: number, operation: (service: LanguageService) => T, validator: (arg: T) => void) { + let checks = 0; + const token: HostCancellationToken = { + isCancellationRequested() { + checks++; + const result = checks >= cancelAfter; + if (result) { + checks = -Infinity; // Cancel just once, then disable cancellation, effectively + } + return result; + } + }; + const adapter = new Harness.LanguageService.NativeLanguageServiceAdapter(token); + const host = adapter.getHost(); + host.addScript("file.ts", content, /*isRootFile*/ true); + const service = adapter.getLanguageService(); + assertCancelled(() => operation(service)); + validator(operation(service)); + } + + /** + * We don't just use `assert.throws` because it doesn't validate instances for thrown objects which do not inherit from `Error` + */ + function assertCancelled(cb: () => void) { + let caught: any; + try { + cb(); + } + catch (e) { + caught = e; + } + assert.exists(caught, "Expected operation to be cancelled, but was not"); + assert.instanceOf(caught, OperationCanceledException); + } +} \ No newline at end of file diff --git a/src/services/completions.ts b/src/services/completions.ts index 236823992fc..f5aba7f99e8 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -534,6 +534,7 @@ namespace ts.Completions { formatContext: formatting.FormatContext, getCanonicalFileName: GetCanonicalFileName, preferences: UserPreferences, + cancellationToken: CancellationToken, ): CompletionEntryDetails { const typeChecker = program.getTypeChecker(); const compilerOptions = program.getCompilerOptions(); @@ -544,7 +545,7 @@ namespace ts.Completions { const stringLiteralCompletions = !contextToken || !isStringLiteralLike(contextToken) ? undefined : getStringLiteralCompletionEntries(sourceFile, contextToken, position, typeChecker, compilerOptions, host); - return stringLiteralCompletions && stringLiteralCompletionDetails(name, contextToken, stringLiteralCompletions, sourceFile, typeChecker); + return stringLiteralCompletions && stringLiteralCompletionDetails(name, contextToken, stringLiteralCompletions, sourceFile, typeChecker, cancellationToken); } // Compute all the completion symbols again. @@ -566,7 +567,7 @@ namespace ts.Completions { case "symbol": { const { symbol, location, symbolToOriginInfoMap, previousToken } = symbolCompletion; const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, typeChecker, host, compilerOptions, sourceFile, previousToken, formatContext, getCanonicalFileName, program.getSourceFiles(), preferences); - return createCompletionDetailsForSymbol(symbol, typeChecker, sourceFile, location, codeActions, sourceDisplay); + return createCompletionDetailsForSymbol(symbol, typeChecker, sourceFile, location, cancellationToken, codeActions, sourceDisplay); } case "none": // Didn't find a symbol with this name. See if we can find a keyword instead. @@ -574,12 +575,15 @@ namespace ts.Completions { } } - function createCompletionDetailsForSymbol(symbol: Symbol, checker: TypeChecker, sourceFile: SourceFile, location: Node, codeActions?: CodeAction[], sourceDisplay?: SymbolDisplayPart[]): CompletionEntryDetails { - const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, SemanticMeaning.All); + function createCompletionDetailsForSymbol(symbol: Symbol, checker: TypeChecker, sourceFile: SourceFile, location: Node, cancellationToken: CancellationToken, codeActions?: CodeAction[], sourceDisplay?: SymbolDisplayPart[]): CompletionEntryDetails { + const { displayParts, documentation, symbolKind, tags } = + checker.runWithCancellationToken(cancellationToken, checker => + SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, SemanticMeaning.All) + ); return createCompletionDetails(symbol.name, SymbolDisplay.getSymbolModifiers(symbol), symbolKind, displayParts, documentation, tags, codeActions, sourceDisplay); } - function stringLiteralCompletionDetails(name: string, location: Node, completion: StringLiteralCompletion, sourceFile: SourceFile, checker: TypeChecker): CompletionEntryDetails | undefined { + function stringLiteralCompletionDetails(name: string, location: Node, completion: StringLiteralCompletion, sourceFile: SourceFile, checker: TypeChecker, cancellationToken: CancellationToken): CompletionEntryDetails | undefined { switch (completion.kind) { case StringLiteralCompletionKind.Paths: { const match = find(completion.paths, p => p.name === name); @@ -587,7 +591,7 @@ namespace ts.Completions { } case StringLiteralCompletionKind.Properties: { const match = find(completion.symbols, s => s.name === name); - return match && createCompletionDetailsForSymbol(match, checker, sourceFile, location); + return match && createCompletionDetailsForSymbol(match, checker, sourceFile, location, cancellationToken); } case StringLiteralCompletionKind.Types: return find(completion.types, t => t.value === name) ? createCompletionDetails(name, ScriptElementKindModifier.none, ScriptElementKind.typeElement, [textPart(name)]) : undefined; diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 1b4e81928c0..2be21476fab 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -45,7 +45,10 @@ namespace ts.FindAllReferences { const checker = program.getTypeChecker(); return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined(referencedSymbols, ({ definition, references }) => // Only include referenced symbols that have a valid definition. - definition && { definition: definitionToReferencedSymbolDefinitionInfo(definition, checker, node), references: references.map(toReferenceEntry) }); + definition && { + definition: checker.runWithCancellationToken(cancellationToken, checker => definitionToReferencedSymbolDefinitionInfo(definition, checker, node)), + references: references.map(toReferenceEntry) + }); } export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray, sourceFile: SourceFile, position: number): ImplementationLocation[] { diff --git a/src/services/services.ts b/src/services/services.ts index 08e3c960d7a..9b427452650 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1424,7 +1424,9 @@ namespace ts { host, formattingOptions && formatting.getFormatContext(formattingOptions), getCanonicalFileName, - preferences); + preferences, + cancellationToken, + ); } function getCompletionEntrySymbol(fileName: string, position: number, name: string, source?: string): Symbol { @@ -1465,7 +1467,7 @@ namespace ts { kind: ScriptElementKind.unknown, kindModifiers: ScriptElementKindModifier.none, textSpan: createTextSpanFromNode(node, sourceFile), - displayParts: typeToDisplayParts(typeChecker, type, getContainerNode(node)), + displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(node))), documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined, tags: type.symbol ? type.symbol.getJsDocTags() : undefined }; @@ -1474,7 +1476,9 @@ namespace ts { return undefined; } - const { symbolKind, displayParts, documentation, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(node), node); + const { symbolKind, displayParts, documentation, tags } = typeChecker.runWithCancellationToken(cancellationToken, typeChecker => + SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(node), node) + ); return { kind: symbolKind, kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts index 156539557a3..45cd828f5d7 100644 --- a/src/services/signatureHelp.ts +++ b/src/services/signatureHelp.ts @@ -41,16 +41,16 @@ namespace ts.SignatureHelp { // We didn't have any sig help items produced by the TS compiler. If this is a JS // file, then see if we can figure out anything better. if (isSourceFileJavaScript(sourceFile)) { - return createJavaScriptSignatureHelpItems(argumentInfo, program); + return createJavaScriptSignatureHelpItems(argumentInfo, program, cancellationToken); } return undefined; } - return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo, typeChecker); + return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidates, resolvedSignature, argumentInfo, typeChecker)); } - function createJavaScriptSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program): SignatureHelpItems { + function createJavaScriptSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program, cancellationToken: CancellationToken): SignatureHelpItems { if (argumentInfo.invocation.kind !== SyntaxKind.CallExpression) { return undefined; } @@ -76,7 +76,7 @@ namespace ts.SignatureHelp { if (type) { const callSignatures = type.getCallSignatures(); if (callSignatures && callSignatures.length) { - return createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, typeChecker); + return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, typeChecker)); } } } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 8fd42ce26b6..504d0c18d40 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1842,6 +1842,12 @@ declare namespace ts { getSuggestionForNonexistentModule(node: Identifier, target: Symbol): string | undefined; getBaseConstraintOfType(type: Type): Type | undefined; getDefaultFromTypeParameter(type: Type): Type | undefined; + /** + * Depending on the operation performed, it may be appropriate to throw away the checker + * if the cancellation token is triggered. Typically, if it is used for error checking + * and the operation is cancelled, then it should be discarded, otherwise it is safe to keep. + */ + runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) => T): T; } enum NodeBuilderFlags { None = 0, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 03091849332..967fe44aab6 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1842,6 +1842,12 @@ declare namespace ts { getSuggestionForNonexistentModule(node: Identifier, target: Symbol): string | undefined; getBaseConstraintOfType(type: Type): Type | undefined; getDefaultFromTypeParameter(type: Type): Type | undefined; + /** + * Depending on the operation performed, it may be appropriate to throw away the checker + * if the cancellation token is triggered. Typically, if it is used for error checking + * and the operation is cancelled, then it should be discarded, otherwise it is safe to keep. + */ + runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) => T): T; } enum NodeBuilderFlags { None = 0, From 3ebcbd4d44d1deb21a84516c980c9f75fd89e13a Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 25 Apr 2018 13:11:35 -0700 Subject: [PATCH 196/229] Handle diagnostic with unknown file (#23681) --- scripts/buildProtocol.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/buildProtocol.ts b/scripts/buildProtocol.ts index 899ab700bf3..3ea7d703cd3 100644 --- a/scripts/buildProtocol.ts +++ b/scripts/buildProtocol.ts @@ -178,7 +178,7 @@ function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptSer ts.sys.writeFile(outputFile, protocolDts); if (diagnostics.length) { - const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file.fileName} line ${d.start}`).join("\n"); + const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file ? d.file.fileName : ""} line ${d.start}`).join("\n"); throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`); } } From 9b05bd5cd79108fcf906b7e0baba6cc735f8a416 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 25 Apr 2018 13:30:34 -0700 Subject: [PATCH 197/229] Remove unnecessary check for ElementAccessExpression#argumentExpression being defined (#23685) --- src/compiler/emitter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 2b01f2fdda1..53d4e56c301 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1441,9 +1441,9 @@ namespace ts { function emitElementAccessExpression(node: ElementAccessExpression) { emitExpression(node.expression); - const openPos = emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node); + emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node); emitExpression(node.argumentExpression); - emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression ? node.argumentExpression.end : openPos, writePunctuation, node); + emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression.end, writePunctuation, node); } function emitCallExpression(node: CallExpression) { From b2bfccfce4dc725515907cb8842699965404cf00 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 25 Apr 2018 13:59:40 -0700 Subject: [PATCH 198/229] Prototype-property assignment:fix name resolution crash (#23680) --- src/compiler/checker.ts | 12 ++++++-- .../reference/jsdocTemplateTag.errors.txt | 30 +++++++++++++++++++ .../reference/jsdocTemplateTag.symbols | 9 ++++++ .../reference/jsdocTemplateTag.types | 13 ++++++++ .../conformance/jsdoc/jsdocTemplateTag.ts | 6 ++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/jsdocTemplateTag.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f3be433aec1..65342c51881 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2134,14 +2134,22 @@ namespace ts { return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol); } + /** + * For prototype-property methods like `A.prototype.m = function () ...`, try to resolve names in the scope of `A` too. + * Note that prototype-property assignment to locations outside the current file (eg globals) doesn't work, so + * name resolution won't work either. + */ function resolveEntityNameFromJSPrototype(name: Identifier, meaning: SymbolFlags) { if (isJSDocTypeReference(name.parent) && isJSDocTag(name.parent.parent.parent)) { const host = getJSDocHost(name.parent.parent.parent as JSDocTag); if (isExpressionStatement(host) && isBinaryExpression(host.expression) && getSpecialPropertyAssignmentKind(host.expression) === SpecialPropertyAssignmentKind.PrototypeProperty) { - const secondaryLocation = getSymbolOfNode(host.expression.left).parent.valueDeclaration; - return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true); + const symbol = getSymbolOfNode(host.expression.left); + if (symbol) { + const secondaryLocation = symbol.parent.valueDeclaration; + return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true); + } } } } diff --git a/tests/baselines/reference/jsdocTemplateTag.errors.txt b/tests/baselines/reference/jsdocTemplateTag.errors.txt new file mode 100644 index 00000000000..c8b3e92f8c0 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag.errors.txt @@ -0,0 +1,30 @@ +tests/cases/conformance/jsdoc/forgot.js(23,19): error TS2339: Property 'animate' does not exist on type 'Element'. + + +==== tests/cases/conformance/jsdoc/forgot.js (1 errors) ==== + /** + * @param {T} a + * @template T + */ + function f(a) { + return () => a + } + let n = f(1)() + + /** + * @param {T} a + * @template T + * @returns {function(): T} + */ + function g(a) { + return () => a + } + let s = g('hi')() + + /** + * @param {Array.} keyframes - Can't look up types on Element since it's a global in another file. (But it shouldn't crash). + */ + Element.prototype.animate = function(keyframes) {}; + ~~~~~~~ +!!! error TS2339: Property 'animate' does not exist on type 'Element'. + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocTemplateTag.symbols b/tests/baselines/reference/jsdocTemplateTag.symbols index 98eee628178..235f26c330e 100644 --- a/tests/baselines/reference/jsdocTemplateTag.symbols +++ b/tests/baselines/reference/jsdocTemplateTag.symbols @@ -30,3 +30,12 @@ let s = g('hi')() >s : Symbol(s, Decl(forgot.js, 17, 3)) >g : Symbol(g, Decl(forgot.js, 7, 14)) +/** + * @param {Array.} keyframes - Can't look up types on Element since it's a global in another file. (But it shouldn't crash). + */ +Element.prototype.animate = function(keyframes) {}; +>Element.prototype : Symbol(prototype, Decl(lib.dom.d.ts, --, --)) +>Element : Symbol(Element, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --)) +>prototype : Symbol(prototype, Decl(lib.dom.d.ts, --, --)) +>keyframes : Symbol(keyframes, Decl(forgot.js, 22, 37)) + diff --git a/tests/baselines/reference/jsdocTemplateTag.types b/tests/baselines/reference/jsdocTemplateTag.types index b1d8c46720d..7917329b3e6 100644 --- a/tests/baselines/reference/jsdocTemplateTag.types +++ b/tests/baselines/reference/jsdocTemplateTag.types @@ -38,3 +38,16 @@ let s = g('hi')() >g : (a: T) => () => T >'hi' : "hi" +/** + * @param {Array.} keyframes - Can't look up types on Element since it's a global in another file. (But it shouldn't crash). + */ +Element.prototype.animate = function(keyframes) {}; +>Element.prototype.animate = function(keyframes) {} : (keyframes: any[]) => void +>Element.prototype.animate : any +>Element.prototype : Element +>Element : { new (): Element; prototype: Element; } +>prototype : Element +>animate : any +>function(keyframes) {} : (keyframes: any[]) => void +>keyframes : any[] + diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateTag.ts b/tests/cases/conformance/jsdoc/jsdocTemplateTag.ts index 79dc083a952..e69756c0941 100644 --- a/tests/cases/conformance/jsdoc/jsdocTemplateTag.ts +++ b/tests/cases/conformance/jsdoc/jsdocTemplateTag.ts @@ -1,6 +1,7 @@ // @allowJs: true // @checkJs: true // @noEmit: true +// @lib: dom,esnext // @Filename: forgot.js /** * @param {T} a @@ -20,3 +21,8 @@ function g(a) { return () => a } let s = g('hi')() + +/** + * @param {Array.} keyframes - Can't look up types on Element since it's a global in another file. (But it shouldn't crash). + */ +Element.prototype.animate = function(keyframes) {}; From 4dc4b8d777a13307aeebde85a96bf2f8cdf4e3b2 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 25 Apr 2018 15:24:36 -0700 Subject: [PATCH 199/229] Remove unused property 'referencedDiagnostics' (#23688) --- src/harness/harness.ts | 8 ++------ src/services/services.ts | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/harness/harness.ts b/src/harness/harness.ts index 9e6978f2a15..9fe26ed51c3 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -304,14 +304,13 @@ namespace Utils { o.containsParseError = true; } - ts.forEach(Object.getOwnPropertyNames(n), propertyName => { + for (const propertyName of Object.getOwnPropertyNames(n) as ReadonlyArray) { switch (propertyName) { case "parent": case "symbol": case "locals": case "localSymbol": case "kind": - case "semanticDiagnostics": case "id": case "nodeCount": case "symbolCount": @@ -334,7 +333,6 @@ namespace Utils { } break; - case "referenceDiagnostics": case "parseDiagnostics": o[propertyName] = convertDiagnostics((n)[propertyName]); break; @@ -355,9 +353,7 @@ namespace Utils { default: o[propertyName] = (n)[propertyName]; } - - return undefined; - }); + } return o; } diff --git a/src/services/services.ts b/src/services/services.ts index 9b427452650..f17b7698a87 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -546,7 +546,6 @@ namespace ts { public typeReferenceDirectives: FileReference[]; public syntacticDiagnostics: Diagnostic[]; - public referenceDiagnostics: Diagnostic[]; public parseDiagnostics: Diagnostic[]; public bindDiagnostics: Diagnostic[]; From 4a6888a85035bfe7c7459dd0996e05980db40ced Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 25 Apr 2018 15:53:06 -0700 Subject: [PATCH 200/229] There exist type parameters with symbols but without TypeParameterDeclaration nodes (#23690) * There exist type parameters with symbols but without TypeParameterDeclaration nodes * Add test --- src/compiler/checker.ts | 3 +- .../reference/noCrashOnThisTypeUsage.js | 48 +++++++++++ .../reference/noCrashOnThisTypeUsage.symbols | 73 +++++++++++++++++ .../reference/noCrashOnThisTypeUsage.types | 80 +++++++++++++++++++ .../cases/compiler/noCrashOnThisTypeUsage.ts | 26 ++++++ 5 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/noCrashOnThisTypeUsage.js create mode 100644 tests/baselines/reference/noCrashOnThisTypeUsage.symbols create mode 100644 tests/baselines/reference/noCrashOnThisTypeUsage.types create mode 100644 tests/cases/compiler/noCrashOnThisTypeUsage.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 65342c51881..2c4999e516f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7296,7 +7296,8 @@ namespace ts { } function getConstraintDeclaration(type: TypeParameter) { - return type.symbol && getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter).constraint; + const decl = type.symbol && getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter); + return decl && decl.constraint; } function getInferredTypeParameterConstraint(typeParameter: TypeParameter) { diff --git a/tests/baselines/reference/noCrashOnThisTypeUsage.js b/tests/baselines/reference/noCrashOnThisTypeUsage.js new file mode 100644 index 00000000000..32fb972c865 --- /dev/null +++ b/tests/baselines/reference/noCrashOnThisTypeUsage.js @@ -0,0 +1,48 @@ +//// [noCrashOnThisTypeUsage.ts] +interface IListenable { + changeListeners: Function[] | null + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void +} + +function notifyListeners(listenable: IListenable, change: T) { +} + +export class ObservableValue { + constructor( + public value: T + ) { + const newValue: T = value; + const oldValue: any = null; + notifyListeners(this, { + type: "update", + object: this, + newValue, + oldValue + }); + } + changeListeners: Function[] | null = []; + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {} +} + +//// [noCrashOnThisTypeUsage.js] +"use strict"; +exports.__esModule = true; +function notifyListeners(listenable, change) { +} +var ObservableValue = /** @class */ (function () { + function ObservableValue(value) { + this.value = value; + this.changeListeners = []; + var newValue = value; + var oldValue = null; + notifyListeners(this, { + type: "update", + object: this, + newValue: newValue, + oldValue: oldValue + }); + } + ObservableValue.prototype.observe = function (handler, fireImmediately) { }; + return ObservableValue; +}()); +exports.ObservableValue = ObservableValue; diff --git a/tests/baselines/reference/noCrashOnThisTypeUsage.symbols b/tests/baselines/reference/noCrashOnThisTypeUsage.symbols new file mode 100644 index 00000000000..84ab25a3392 --- /dev/null +++ b/tests/baselines/reference/noCrashOnThisTypeUsage.symbols @@ -0,0 +1,73 @@ +=== tests/cases/compiler/noCrashOnThisTypeUsage.ts === +interface IListenable { +>IListenable : Symbol(IListenable, Decl(noCrashOnThisTypeUsage.ts, 0, 0)) + + changeListeners: Function[] | null +>changeListeners : Symbol(IListenable.changeListeners, Decl(noCrashOnThisTypeUsage.ts, 0, 23)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void +>observe : Symbol(IListenable.observe, Decl(noCrashOnThisTypeUsage.ts, 1, 38)) +>handler : Symbol(handler, Decl(noCrashOnThisTypeUsage.ts, 2, 12)) +>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 2, 22)) +>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 2, 34)) +>fireImmediately : Symbol(fireImmediately, Decl(noCrashOnThisTypeUsage.ts, 2, 59)) +} + +function notifyListeners(listenable: IListenable, change: T) { +>notifyListeners : Symbol(notifyListeners, Decl(noCrashOnThisTypeUsage.ts, 3, 1)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 5, 25)) +>listenable : Symbol(listenable, Decl(noCrashOnThisTypeUsage.ts, 5, 28)) +>IListenable : Symbol(IListenable, Decl(noCrashOnThisTypeUsage.ts, 0, 0)) +>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 5, 52)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 5, 25)) +} + +export class ObservableValue { +>ObservableValue : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29)) + + constructor( + public value: T +>value : Symbol(ObservableValue.value, Decl(noCrashOnThisTypeUsage.ts, 9, 16)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29)) + + ) { + const newValue: T = value; +>newValue : Symbol(newValue, Decl(noCrashOnThisTypeUsage.ts, 12, 13)) +>T : Symbol(T, Decl(noCrashOnThisTypeUsage.ts, 8, 29)) +>value : Symbol(value, Decl(noCrashOnThisTypeUsage.ts, 9, 16)) + + const oldValue: any = null; +>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 13, 13)) + + notifyListeners(this, { +>notifyListeners : Symbol(notifyListeners, Decl(noCrashOnThisTypeUsage.ts, 3, 1)) +>this : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1)) + + type: "update", +>type : Symbol(type, Decl(noCrashOnThisTypeUsage.ts, 14, 31)) + + object: this, +>object : Symbol(object, Decl(noCrashOnThisTypeUsage.ts, 15, 27)) +>this : Symbol(ObservableValue, Decl(noCrashOnThisTypeUsage.ts, 6, 1)) + + newValue, +>newValue : Symbol(newValue, Decl(noCrashOnThisTypeUsage.ts, 16, 25)) + + oldValue +>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 17, 21)) + + }); + } + changeListeners: Function[] | null = []; +>changeListeners : Symbol(ObservableValue.changeListeners, Decl(noCrashOnThisTypeUsage.ts, 20, 5)) +>Function : Symbol(Function, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {} +>observe : Symbol(ObservableValue.observe, Decl(noCrashOnThisTypeUsage.ts, 21, 44)) +>handler : Symbol(handler, Decl(noCrashOnThisTypeUsage.ts, 22, 12)) +>change : Symbol(change, Decl(noCrashOnThisTypeUsage.ts, 22, 22)) +>oldValue : Symbol(oldValue, Decl(noCrashOnThisTypeUsage.ts, 22, 34)) +>fireImmediately : Symbol(fireImmediately, Decl(noCrashOnThisTypeUsage.ts, 22, 59)) +} diff --git a/tests/baselines/reference/noCrashOnThisTypeUsage.types b/tests/baselines/reference/noCrashOnThisTypeUsage.types new file mode 100644 index 00000000000..81851f96a5e --- /dev/null +++ b/tests/baselines/reference/noCrashOnThisTypeUsage.types @@ -0,0 +1,80 @@ +=== tests/cases/compiler/noCrashOnThisTypeUsage.ts === +interface IListenable { +>IListenable : IListenable + + changeListeners: Function[] | null +>changeListeners : Function[] | null +>Function : Function +>null : null + + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void +>observe : (handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean | undefined) => void +>handler : (change: any, oldValue?: any) => void +>change : any +>oldValue : any +>fireImmediately : boolean | undefined +} + +function notifyListeners(listenable: IListenable, change: T) { +>notifyListeners : (listenable: IListenable, change: T) => void +>T : T +>listenable : IListenable +>IListenable : IListenable +>change : T +>T : T +} + +export class ObservableValue { +>ObservableValue : ObservableValue +>T : T + + constructor( + public value: T +>value : T +>T : T + + ) { + const newValue: T = value; +>newValue : T +>T : T +>value : T + + const oldValue: any = null; +>oldValue : any +>null : null + + notifyListeners(this, { +>notifyListeners(this, { type: "update", object: this, newValue, oldValue }) : void +>notifyListeners : (listenable: IListenable, change: T) => void +>this : this +>{ type: "update", object: this, newValue, oldValue } : { type: string; object: this; newValue: T; oldValue: any; } + + type: "update", +>type : string +>"update" : "update" + + object: this, +>object : this +>this : this + + newValue, +>newValue : T + + oldValue +>oldValue : any + + }); + } + changeListeners: Function[] | null = []; +>changeListeners : Function[] | null +>Function : Function +>null : null +>[] : never[] + + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {} +>observe : (handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean | undefined) => void +>handler : (change: any, oldValue?: any) => void +>change : any +>oldValue : any +>fireImmediately : boolean | undefined +} diff --git a/tests/cases/compiler/noCrashOnThisTypeUsage.ts b/tests/cases/compiler/noCrashOnThisTypeUsage.ts new file mode 100644 index 00000000000..7f3832a70d7 --- /dev/null +++ b/tests/cases/compiler/noCrashOnThisTypeUsage.ts @@ -0,0 +1,26 @@ +// @strict: true + +interface IListenable { + changeListeners: Function[] | null + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean): void +} + +function notifyListeners(listenable: IListenable, change: T) { +} + +export class ObservableValue { + constructor( + public value: T + ) { + const newValue: T = value; + const oldValue: any = null; + notifyListeners(this, { + type: "update", + object: this, + newValue, + oldValue + }); + } + changeListeners: Function[] | null = []; + observe(handler: (change: any, oldValue?: any) => void, fireImmediately?: boolean) {} +} \ No newline at end of file From 4a379d66d42e5028485b34e6675eea19527c0c28 Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 25 Apr 2018 16:15:06 -0700 Subject: [PATCH 201/229] Use @types/travis-fold (#23694) --- package-lock.json | 1558 ++++++++++++++++-------------------- package.json | 7 +- scripts/types/ambient.d.ts | 1 - 3 files changed, 672 insertions(+), 894 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2e1c6f6207e..265d4233ad8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "@types/browserify": { "version": "12.0.33", "resolved": "https://registry.npmjs.org/@types/browserify/-/browserify-12.0.33.tgz", - "integrity": "sha1-5hlxwPmFvx93CQSDJkk/ELDdeL0=", + "integrity": "sha512-mY6dYfq1Ns3Xqz/JFUcyoWaXtm0XDoNhkU1vCwM/ULM5zqNL+SbtacJhce/JCgPeCdbqdVqq77tJ4HwdtypSxg==", "dev": true, "requires": { "@types/insert-module-globals": "7.0.0", @@ -46,21 +46,21 @@ } }, "@types/chai": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.2.tgz", - "integrity": "sha512-D8uQwKYUw2KESkorZ27ykzXgvkDJYXVEihGklgfp5I4HUP8D6IxtcdLTMB1emjQiWzV7WZ5ihm1cxIzVwjoleQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.3.tgz", + "integrity": "sha512-f5dXGzOJycyzSMdaXVhiBhauL4dYydXwVpavfQ1mVCaGjR56a9QfklXObUxlIY9bGTmCPHEEZ04I16BZ/8w5ww==", "dev": true }, "@types/convert-source-map": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@types/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-1NGA3WrcXLaK2ZvVbgPWN4gfRhY=", + "integrity": "sha512-laiDIXqqthjJlyAMYAXOtN3N8+UlbM+KvZi4BaY5ZOekmVkBs/UxfK5O0HWeJVG2eW8F+Mu2ww13fTX+kY1FlQ==", "dev": true }, "@types/del": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/del/-/del-3.0.0.tgz", - "integrity": "sha1-HIzYtuONo7VyNSyo6vVSeTFCYog=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/del/-/del-3.0.1.tgz", + "integrity": "sha512-y6qRq6raBuu965clKgx6FHuiPu3oHdtmzMPXi8Uahsjdq1L6DL5fS/aY5/s71YwM7k6K1QIWvem5vNwlnNGIkQ==", "dev": true, "requires": { "@types/glob": "5.0.35" @@ -86,7 +86,7 @@ "@types/gulp": { "version": "3.8.36", "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-3.8.36.tgz", - "integrity": "sha1-Eer1g78FNGabT/qb/tUVV/qgCkw=", + "integrity": "sha512-u6/zWPzYRNPAtvyFJ3/RSXjmBaBM1dVs5kW22/jU6J786ZGLfSndhLoNOpFI6FGQvqTA+QzFHjSMhpkAN+wxcQ==", "dev": true, "requires": { "@types/node": "8.5.5", @@ -97,7 +97,7 @@ "@types/gulp-concat": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/gulp-concat/-/gulp-concat-0.0.32.tgz", - "integrity": "sha1-ckhgKLHPX6qUyMHPNMYmUxzsrNY=", + "integrity": "sha512-CUCFADlITzzBfBa2bdGzhKtvBr4eFh+evb+4igVbvPoO5RyPfHifmyQlZl6lM7q19+OKncRlFXDU7B4X9Ayo2g==", "dev": true, "requires": { "@types/node": "8.5.5" @@ -106,7 +106,7 @@ "@types/gulp-help": { "version": "0.0.34", "resolved": "https://registry.npmjs.org/@types/gulp-help/-/gulp-help-0.0.34.tgz", - "integrity": "sha1-Dm1mcYySiWZPLtdaIaDmXXqIM+w=", + "integrity": "sha512-MkW7psZznxxJg2MBk2P2qHE+T8jEZVFz3FG/qGjUYazkyJt7hBJWx5Nuewmay5RVNtUvSWPrdZLr/WTXY3T/6A==", "dev": true, "requires": { "@types/gulp": "3.8.36", @@ -117,7 +117,7 @@ "@types/gulp-newer": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/@types/gulp-newer/-/gulp-newer-0.0.31.tgz", - "integrity": "sha1-818j0eT+DXuP9pnknRwhdmy546c=", + "integrity": "sha512-e7J/Zv5Wd7CC0WpuA2syWVitgwrkG0u221e41w7r07XUR6hMH6kHPkq9tUrusHkbeW8QbuLbis5fODOwQCyggQ==", "dev": true, "requires": { "@types/node": "8.5.5" @@ -126,7 +126,7 @@ "@types/gulp-sourcemaps": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/gulp-sourcemaps/-/gulp-sourcemaps-0.0.32.tgz", - "integrity": "sha1-557mF+DLFXKYdL5FM/5ZwHeToXU=", + "integrity": "sha512-+7BAmptW2bxyJnJcCEuie7vLoop3FwWgCdBMzyv7MYXED/HeNMeQuX7uPCkp4vfU1TTu4CYFH0IckNPvo0VePA==", "dev": true, "requires": { "@types/node": "8.5.5" @@ -135,7 +135,7 @@ "@types/insert-module-globals": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@types/insert-module-globals/-/insert-module-globals-7.0.0.tgz", - "integrity": "sha1-jRWN5KY4To2qE7PWPuurbV9nd30=", + "integrity": "sha512-zudCJPwluh1VUDB6Gl/OQdRp+fYy3+47huJB/JMQubMS2p+sH18MCVK4WUz3FqaWLB12yh5ELxVR/+tqwlm/qA==", "dev": true, "requires": { "@types/node": "8.5.5" @@ -144,7 +144,7 @@ "@types/merge2": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/merge2/-/merge2-1.1.4.tgz", - "integrity": "sha1-CmUOHMIVove4BALqtraiNuYC96M=", + "integrity": "sha512-GjaXY4OultxbaOOk7lCLO7xvEcFpdjExC605YmfI6X29vhHKpJfMWKCDZd3x+BITrZaXKg97DgV/SdGVSwdzxA==", "dev": true, "requires": { "@types/node": "8.5.5" @@ -165,28 +165,28 @@ "@types/mkdirp": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha1-UDqs/lzCcD1UhDJrGyfvpnoznB8=", + "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", "dev": true, "requires": { "@types/node": "8.5.5" } }, "@types/mocha": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.0.0.tgz", - "integrity": "sha512-ZS0vBV7Jn5Z/Q4T3VXauEKMDCV8nWOtJJg90OsDylkYJiQwcWtKuLzohWzrthBkerUF7DLMmJcwOPEP0i/AOXw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-YeDiSEzznwZwwp766SJ6QlrTyBYUGPSIwmREHVTmktUYiT/WADdWtpt9iH0KuUSf8lZLdI4lP0X6PBzPo5//JQ==", "dev": true }, "@types/node": { "version": "8.5.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz", - "integrity": "sha1-b56BZK4aVam+sdJXHPt6z51yDGE=", + "integrity": "sha512-JRnfoh0Ll4ElmIXKxbUfcOodkGvcNHljct6mO1X9hE/mlrMzAx0hYCLAD7sgT53YAY1HdlpzUcV0CkmDqUqTuA==", "dev": true }, "@types/orchestrator": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@types/orchestrator/-/orchestrator-0.3.2.tgz", - "integrity": "sha1-zRXGzql4oyuY5QVCOcvMeOVWcfE=", + "integrity": "sha512-cKB4yTX0wGaRCSkdHDX2fkGQbMAA8UOshC2U7DQky1CE5o+5q2iQQ8VkbPbE/88uaTtsusvBPMcCX7dgmjxBhQ==", "dev": true, "requires": { "@types/node": "8.5.5", @@ -202,7 +202,7 @@ "@types/run-sequence": { "version": "0.0.30", "resolved": "https://registry.npmjs.org/@types/run-sequence/-/run-sequence-0.0.30.tgz", - "integrity": "sha1-s6kMn9KaXu3lgTXdAl6zrEu7Vg4=", + "integrity": "sha512-XwGr1b4yCGUILKeBkzmeWcxmGHQ0vFFFpA6D6y1yLO6gKmYorF+PHqdU5KG+nWt38OvtrkDptmrSmlHX/XtpLw==", "dev": true, "requires": { "@types/gulp": "3.8.36", @@ -218,10 +218,16 @@ "@types/node": "8.5.5" } }, + "@types/travis-fold": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@types/travis-fold/-/travis-fold-0.1.0.tgz", + "integrity": "sha512-qrXB0Div8vIzA8P809JRlh9lD4mSOYwRBJbU1zcj0BWhULP15Zx0oQyJtjaOnkNR5RZcYQDbgimj40M1GDmhcQ==", + "dev": true + }, "@types/vinyl": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.2.tgz", - "integrity": "sha1-TzuNro9YKNOADvcJsM/0iO6FLeM=", + "integrity": "sha512-2iYpNuOl98SrLPBZfEN9Mh2JCJ2EI9HU35SfgBEb51DcmaHkhp8cKMblYeBqMQiwXMgAD3W60DbQ4i/UdLiXhw==", "dev": true, "requires": { "@types/node": "8.5.5" @@ -230,7 +236,7 @@ "@types/xml2js": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.2.tgz", - "integrity": "sha1-pLhLOHn/1HEJU/2Syr/emopOhFY=", + "integrity": "sha512-8aKUBSj3oGcnuiBmDLm3BIk09RYg01mz9HlQ2u4aS17oJ25DxjQrEUVGFSBVNOfM45pQW4OjcBPplq6r/exJdA==", "dev": true, "requires": { "@types/node": "8.5.5" @@ -377,9 +383,9 @@ "dev": true }, "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "1.0.3" @@ -394,7 +400,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, "arr-union": { @@ -436,7 +442,7 @@ "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha1-42jqFfibxwaff/uJrsOmx9SsItQ=", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true }, "array-union": { @@ -460,12 +466,6 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, "asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", @@ -474,7 +474,7 @@ "requires": { "bn.js": "4.11.8", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "assert": { @@ -514,9 +514,9 @@ "dev": true }, "atob": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz", - "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.0.tgz", + "integrity": "sha512-SuiKH8vbsOyCALjA/+EINmt/Kdl+TQPrtFgW7XZZcwtryFu9e5kQoX3bjCW6mIvGH1fbeAZZuvwGR5IlBRznGw==", "dev": true }, "babel-code-frame": { @@ -566,22 +566,62 @@ "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { "cache-base": "1.0.1", - "class-utils": "0.3.5", + "class-utils": "0.3.6", "component-emitter": "1.2.1", "define-property": "1.0.0", "isobject": "3.0.1", - "mixin-deep": "1.3.0", + "mixin-deep": "1.3.1", "pascalcase": "0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } } }, "base64-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", - "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true }, "beeper": { @@ -597,9 +637,9 @@ "dev": true }, "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "1.0.0", @@ -607,22 +647,32 @@ } }, "braces": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz", - "integrity": "sha1-pGlBy1+0khVrPWplbgbDU2Tj5m4=", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { "arr-flatten": "1.1.0", "array-unique": "0.3.2", - "define-property": "1.0.0", "extend-shallow": "2.0.1", "fill-range": "4.0.0", "isobject": "3.0.1", "repeat-element": "1.1.2", - "snapdragon": "0.8.1", + "snapdragon": "0.8.2", "snapdragon-node": "2.1.1", "split-string": "3.1.0", - "to-regex": "3.0.1" + "to-regex": "3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } } }, "brorand": { @@ -640,7 +690,7 @@ "JSONStream": "1.3.2", "combine-source-map": "0.8.0", "defined": "1.0.0", - "safe-buffer": "5.1.1", + "safe-buffer": "5.1.2", "through2": "2.0.3", "umd": "3.0.3" } @@ -661,9 +711,9 @@ "dev": true }, "browserify": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.1.1.tgz", - "integrity": "sha512-iSH21jK0+IApV8YHOfmGt1qsGd74oflQ1Ko/28JOkWLFNBngAQfKb6WYIJ9CufH8vycqKX1sYU3y7ZrVhwevAg==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.0.tgz", + "integrity": "sha512-yotdAkp/ZbgDesHQBYU37zjc29JDH4iXT8hjzM1fdUVWogjARX0S1cKeX24Ci6zZ+jG+ADmCTRt6xvtmJnI+BQ==", "dev": true, "requires": { "JSONStream": "1.3.2", @@ -698,13 +748,13 @@ "punycode": "1.4.1", "querystring-es3": "0.2.1", "read-only-stream": "2.0.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "resolve": "1.1.7", "shasum": "1.0.2", "shell-quote": "1.6.1", "stream-browserify": "2.0.1", "stream-http": "2.8.1", - "string_decoder": "1.0.3", + "string_decoder": "1.1.1", "subarg": "1.0.0", "syntax-error": "1.4.0", "through2": "2.0.3", @@ -712,7 +762,7 @@ "tty-browserify": "0.0.1", "url": "0.11.0", "util": "0.10.3", - "vm-browserify": "0.0.4", + "vm-browserify": "1.0.1", "xtend": "4.0.1" } }, @@ -724,27 +774,27 @@ "requires": { "buffer-xor": "1.0.3", "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "browserify-cipher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", - "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { "browserify-aes": "1.2.0", - "browserify-des": "1.0.0", + "browserify-des": "1.0.1", "evp_bytestokey": "1.0.3" } }, "browserify-des": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", - "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", + "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", "dev": true, "requires": { "cipher-base": "1.0.4", @@ -770,11 +820,11 @@ "requires": { "bn.js": "4.11.8", "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", "elliptic": "6.4.0", "inherits": "2.0.3", - "parse-asn1": "5.1.0" + "parse-asn1": "5.1.1" } }, "browserify-zlib": { @@ -792,7 +842,7 @@ "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "dev": true, "requires": { - "base64-js": "1.2.3", + "base64-js": "1.3.0", "ieee754": "1.1.11" } }, @@ -835,7 +885,7 @@ "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { "collection-visit": "1.0.0", @@ -871,15 +921,6 @@ "requires": { "align-text": "0.1.4", "lazy-cache": "1.0.4" - }, - "dependencies": { - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true, - "optional": true - } } }, "chai": { @@ -893,18 +934,18 @@ "deep-eql": "3.0.1", "get-func-name": "2.0.0", "pathval": "1.1.0", - "type-detect": "4.0.5" + "type-detect": "4.0.8" } }, "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz", + "integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==", "dev": true, "requires": { "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" + "supports-color": "5.4.0" } }, "check-error": { @@ -920,19 +961,18 @@ "dev": true, "requires": { "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "class-utils": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.5.tgz", - "integrity": "sha1-F+eTEDdQ+WJ7IXbqNM/RtWWQPIA=", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { "arr-union": "3.1.0", "define-property": "0.2.5", "isobject": "3.0.1", - "lazy-cache": "2.0.2", "static-extend": "0.1.2" }, "dependencies": { @@ -944,63 +984,6 @@ "requires": { "is-descriptor": "0.1.6" } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true } } }, @@ -1026,9 +1009,9 @@ } }, "clone": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", "dev": true }, "clone-buffer": { @@ -1044,14 +1027,14 @@ "dev": true }, "cloneable-readable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", - "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", + "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", "dev": true, "requires": { "inherits": "2.0.3", - "process-nextick-args": "1.0.7", - "through2": "2.0.3" + "process-nextick-args": "2.0.0", + "readable-stream": "2.3.6" } }, "collection-visit": { @@ -1082,7 +1065,7 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha1-k4NDeaHMmgxh+C9S8NBDIiUb1aI=", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, "combine-source-map": { @@ -1131,17 +1114,25 @@ "requires": { "buffer-from": "1.0.0", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "typedarray": "0.0.6" } }, "concat-with-sourcemaps": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.4.tgz", - "integrity": "sha1-9Vs74q60dgGxCi1SWcz7cP0vHdY=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.5.tgz", + "integrity": "sha512-YtnS0VEY+e2Khzsey/6mra9EoM6h/5gxaC0e3mcHpA5yfDxafhygytNmcJWodvUgyXzSiL5MSkPO6bQGgfliHw==", "dev": true, "requires": { - "source-map": "0.5.7" + "source-map": "0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "console-browserify": { @@ -1178,9 +1169,9 @@ "dev": true }, "create-ecdh": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", - "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.1.tgz", + "integrity": "sha512-iZvCCg8XqHQZ1ioNBTzXS/cQSkqkqcPs8xSX4upNB+DAk9Ht3uzQf2J32uAHNCne8LDmKr29AgZrEs4oIrwLuQ==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -1188,28 +1179,29 @@ } }, "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { "cipher-base": "1.0.4", "inherits": "2.0.3", - "ripemd160": "2.0.1", + "md5.js": "1.3.4", + "ripemd160": "2.0.2", "sha.js": "2.4.11" } }, "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { "cipher-base": "1.0.4", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "inherits": "2.0.3", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", "sha.js": "2.4.11" } }, @@ -1219,15 +1211,15 @@ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "browserify-cipher": "1.0.0", + "browserify-cipher": "1.0.1", "browserify-sign": "4.0.4", - "create-ecdh": "4.0.0", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "diffie-hellman": "5.0.2", + "create-ecdh": "4.0.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "diffie-hellman": "5.0.3", "inherits": "2.0.3", - "pbkdf2": "3.0.14", - "public-encrypt": "4.0.0", + "pbkdf2": "3.0.16", + "public-encrypt": "4.0.2", "randombytes": "2.0.6", "randomfill": "1.0.4" } @@ -1303,7 +1295,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" @@ -1347,10 +1339,10 @@ "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha1-38lARACtHI/gI+faHfHBR8S0RN8=", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { - "type-detect": "4.0.5" + "type-detect": "4.0.8" } }, "deep-is": { @@ -1365,7 +1357,7 @@ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", "dev": true, "requires": { - "clone": "1.0.3" + "clone": "1.0.4" } }, "define-properties": { @@ -1379,12 +1371,44 @@ } }, "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "1.0.2", + "isobject": "3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } } }, "defined": { @@ -1401,7 +1425,7 @@ "requires": { "globby": "6.1.0", "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", + "is-path-in-cwd": "1.0.1", "p-map": "1.2.0", "pify": "3.0.0", "rimraf": "2.6.2" @@ -1432,7 +1456,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "detect-file": { @@ -1465,9 +1489,9 @@ "dev": true }, "diffie-hellman": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", - "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -1487,7 +1511,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "duplexify": { @@ -1498,7 +1522,7 @@ "requires": { "end-of-stream": "1.4.1", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "stream-shift": "1.0.0" }, "dependencies": { @@ -1524,7 +1548,7 @@ "hash.js": "1.1.3", "hmac-drbg": "1.0.1", "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", + "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } }, @@ -1670,7 +1694,7 @@ "dev": true, "requires": { "md5.js": "1.3.4", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "expand-brackets": { @@ -1683,9 +1707,9 @@ "define-property": "0.2.5", "extend-shallow": "2.0.1", "posix-character-classes": "0.1.1", - "regex-not": "1.0.0", - "snapdragon": "0.8.1", - "to-regex": "3.0.1" + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -1697,62 +1721,14 @@ "is-descriptor": "0.1.6" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } + "is-extendable": "0.1.1" } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true } } }, @@ -1772,18 +1748,30 @@ "dev": true }, "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "2.0.4" + } + } } }, "extglob": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.3.tgz", - "integrity": "sha1-VeAZ0Mlb+HOUnHN7flFy26hOuyk=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { "array-unique": "0.3.2", @@ -1791,9 +1779,58 @@ "expand-brackets": "2.1.4", "extend-shallow": "2.0.1", "fragment-cache": "0.2.1", - "regex-not": "1.0.0", - "snapdragon": "0.8.1", - "to-regex": "3.0.1" + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } } }, "fancy-log": { @@ -1841,6 +1878,17 @@ "is-number": "3.0.0", "repeat-string": "1.6.1", "to-regex-range": "2.1.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } } }, "find-index": { @@ -1857,7 +1905,7 @@ "requires": { "detect-file": "1.0.0", "is-glob": "3.1.0", - "micromatch": "3.1.5", + "micromatch": "3.1.10", "resolve-dir": "1.0.1" } }, @@ -1893,7 +1941,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "for-in": { @@ -1980,7 +2028,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -2039,7 +2087,7 @@ "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "1.1.11" } }, "readable-stream": { @@ -2093,11 +2141,11 @@ "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha1-bXcPDrUjrHgWTXK15xqIdyZcw+o=", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", "dev": true, "requires": { "global-prefix": "1.0.2", - "is-windows": "1.0.1", + "is-windows": "1.0.2", "resolve-dir": "1.0.1" } }, @@ -2110,7 +2158,7 @@ "expand-tilde": "2.0.2", "homedir-polyfill": "1.0.1", "ini": "1.3.5", - "is-windows": "1.0.1", + "is-windows": "1.0.2", "which": "1.3.0" } }, @@ -2182,9 +2230,9 @@ } }, "glogg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", - "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz", + "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==", "dev": true, "requires": { "sparkles": "1.0.0" @@ -2196,7 +2244,7 @@ "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", "dev": true, "requires": { - "natives": "1.1.1" + "natives": "1.1.3" } }, "growl": { @@ -2269,7 +2317,7 @@ "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", "dev": true, "requires": { - "concat-with-sourcemaps": "1.0.4", + "concat-with-sourcemaps": "1.0.5", "through2": "2.0.3", "vinyl": "2.1.0" } @@ -2429,7 +2477,7 @@ "is-negated-glob": "1.0.0", "ordered-read-streams": "1.0.1", "pumpify": "1.4.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "remove-trailing-separator": "1.1.0", "to-absolute-glob": "2.0.2", "unique-stream": "2.2.1" @@ -2456,7 +2504,7 @@ "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "source-map": { @@ -2489,7 +2537,7 @@ "lead": "1.0.0", "object.assign": "4.1.0", "pumpify": "1.4.0", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "remove-bom-buffer": "3.0.0", "remove-bom-stream": "1.2.0", "resolve-options": "1.1.0", @@ -2565,7 +2613,7 @@ "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", "dev": true, "requires": { - "clone": "1.0.3", + "clone": "1.0.4", "clone-stats": "0.0.1", "replace-ext": "0.0.1" } @@ -2578,7 +2626,7 @@ "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", "dev": true, "requires": { - "glogg": "1.0.0" + "glogg": "1.0.1" } }, "handlebars": { @@ -2682,12 +2730,13 @@ } }, "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "2.0.3" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "hash.js": { @@ -2697,7 +2746,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "minimalistic-assert": "1.0.1" } }, "he": { @@ -2713,7 +2762,7 @@ "dev": true, "requires": { "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", + "minimalistic-assert": "1.0.1", "minimalistic-crypto-utils": "1.0.1" } }, @@ -2744,12 +2793,6 @@ "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==", "dev": true }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2769,7 +2812,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "inline-source-map": { @@ -2807,46 +2850,76 @@ "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha1-OV4a6EsR8mrReV5zwXN45IowFXY=", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", "dev": true, "requires": { "is-relative": "1.0.0", - "is-windows": "1.0.1" + "is-windows": "1.0.2" } }, "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } } }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "3.2.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "1.1.6" + } + } } }, "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } } }, "is-extendable": { @@ -2897,12 +2970,20 @@ } }, "is-odd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz", - "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", + "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", "dev": true, "requires": { - "is-number": "3.0.0" + "is-number": "4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } } }, "is-path-cwd": { @@ -2912,9 +2993,9 @@ "dev": true }, "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "dev": true, "requires": { "is-path-inside": "1.0.1" @@ -2932,7 +3013,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "3.0.1" @@ -2947,7 +3028,7 @@ "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha1-obtpNc6MXboei5dUubLcwCDiJg0=", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "dev": true, "requires": { "is-unc-path": "1.0.0" @@ -2956,7 +3037,7 @@ "is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha1-1zHoiY7QkKEsNSrS6u1Qla0yLJ0=", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "dev": true, "requires": { "unc-path-regex": "0.1.2" @@ -2975,9 +3056,9 @@ "dev": true }, "is-windows": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz", - "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { @@ -3010,7 +3091,7 @@ "esprima": "2.7.3", "glob": "5.0.15", "handlebars": "4.0.11", - "js-yaml": "3.10.0", + "js-yaml": "3.11.0", "mkdirp": "0.5.1", "nopt": "3.0.6", "once": "1.4.0", @@ -3051,9 +3132,9 @@ } }, "jake": { - "version": "8.0.15", - "resolved": "https://registry.npmjs.org/jake/-/jake-8.0.15.tgz", - "integrity": "sha1-8Np9WOeQrBqPhubuDxk+XZIw6rs=", + "version": "8.0.16", + "resolved": "https://registry.npmjs.org/jake/-/jake-8.0.16.tgz", + "integrity": "sha512-qUTOVCKFkiz3tHgV1WMy7HTxDZgo+sO4X9GxFLAU+Mks4WsDGe9+ONHK6tPsSp8I3x6sPl0TwGbXHwTOhTyzog==", "dev": true, "requires": { "async": "0.9.2", @@ -3101,19 +3182,19 @@ "dev": true }, "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha1-LnhEFka9RoLpY/IrbpKCPDCcYtw=", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "dev": true, "requires": { - "argparse": "1.0.9", + "argparse": "1.0.10", "esprima": "4.0.0" }, "dependencies": { "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", "dev": true } } @@ -3148,7 +3229,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", "dev": true }, "labeled-stream-splicer": { @@ -3171,13 +3252,11 @@ } }, "lazy-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", - "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", "dev": true, - "requires": { - "set-getter": "0.1.0" - } + "optional": true }, "lazystream": { "version": "1.0.0", @@ -3185,7 +3264,7 @@ "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "lead": { @@ -3384,30 +3463,13 @@ "es5-ext": "0.10.42" } }, - "make-error": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", - "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", - "dev": true - }, "make-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.0.tgz", - "integrity": "sha1-V7713IXSOSO6I3ZzJNjo+PPZaUs=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", "dev": true, "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } + "kind-of": "6.0.2" } }, "map-cache": { @@ -3433,18 +3495,6 @@ "requires": { "hash-base": "3.0.4", "inherits": "2.0.3" - }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" - } - } } }, "memoizee": { @@ -3470,24 +3520,24 @@ "dev": true }, "micromatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.5.tgz", - "integrity": "sha512-ykttrLPQrz1PUJcXjwsTUjGoPJ64StIGNE2lGVD1c9CuguJ+L7/navsE8IcDNndOoCMvYV0qc/exfVbMHkUhvA==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", - "braces": "2.3.0", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", - "extglob": "2.0.3", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", "fragment-cache": "0.2.1", "kind-of": "6.0.2", - "nanomatch": "1.2.7", + "nanomatch": "1.2.9", "object.pick": "1.3.0", - "regex-not": "1.0.0", - "snapdragon": "0.8.1", - "to-regex": "3.0.1" + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" } }, "miller-rabin": { @@ -3501,9 +3551,9 @@ } }, "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true }, "minimalistic-crypto-utils": { @@ -3515,10 +3565,10 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -3528,9 +3578,9 @@ "dev": true }, "mixin-deep": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.0.tgz", - "integrity": "sha1-R6hzK6l3mUV8jB7KKPlRMtfoFQo=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { "for-in": "1.0.2", @@ -3540,7 +3590,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { "is-plain-object": "2.0.4" @@ -3566,9 +3616,9 @@ } }, "mocha": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.5.tgz", - "integrity": "sha512-3MM3UjZ5p8EJrYpG7s+29HAI9G7sTzKEe4+w37Dg0QP7qL4XGsV+Q2xet2cE37AqdgN1OtYQB6Vl98YiPV3PgA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz", + "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==", "dev": true, "requires": { "browser-stdout": "1.3.1", @@ -3579,6 +3629,7 @@ "glob": "7.1.2", "growl": "1.10.3", "he": "1.1.1", + "minimatch": "3.0.4", "mkdirp": "0.5.1", "supports-color": "4.4.0" }, @@ -3630,8 +3681,8 @@ "duplexer2": "0.1.4", "inherits": "2.0.3", "parents": "1.0.1", - "readable-stream": "2.3.3", - "resolve": "1.6.0", + "readable-stream": "2.3.6", + "resolve": "1.7.1", "stream-combiner2": "1.1.1", "subarg": "1.0.0", "through2": "2.0.3", @@ -3639,9 +3690,9 @@ }, "dependencies": { "resolve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", - "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "dev": true, "requires": { "path-parse": "1.0.5" @@ -3700,36 +3751,29 @@ } }, "nanomatch": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.7.tgz", - "integrity": "sha512-/5ldsnyurvEw7wNpxLFgjVvBLMta43niEYOy0CJ4ntcYSbx6bugRUTQeFb4BR/WanEL1o3aQgHuVLHQaB6tOqg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", + "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", "dev": true, "requires": { "arr-diff": "4.0.0", "array-unique": "0.3.2", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", "fragment-cache": "0.2.1", - "is-odd": "1.0.0", - "kind-of": "5.1.0", + "is-odd": "2.0.0", + "is-windows": "1.0.2", + "kind-of": "6.0.2", "object.pick": "1.3.0", - "regex-not": "1.0.0", - "snapdragon": "0.8.1", - "to-regex": "3.0.1" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" } }, "natives": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz", - "integrity": "sha1-ARrM4ffL2H97prMJPWzZOSvhxXQ=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.3.tgz", + "integrity": "sha512-BZGSYV4YOLxzoTK73l0/s/0sH9l8SHs2ocReMH1f8JYSh5FUWu4ZrKCpJdRkWXV6HFR/pZDz7bwWOVAY07q77g==", "dev": true }, "next-tick": { @@ -3791,43 +3835,6 @@ "is-descriptor": "0.1.6" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true - } - } - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -3885,7 +3892,7 @@ "dev": true, "requires": { "for-own": "1.0.0", - "make-iterator": "1.0.0" + "make-iterator": "1.0.1" } }, "object.pick": { @@ -3952,7 +3959,7 @@ "requires": { "end-of-stream": "0.1.5", "sequencify": "0.0.7", - "stream-consume": "0.1.0" + "stream-consume": "0.1.1" } }, "ordered-read-streams": { @@ -3976,7 +3983,7 @@ "p-map": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha1-5OlPMR6rvIYzoeeZCBZfyiYkG2s=", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", "dev": true }, "pako": { @@ -3995,16 +4002,16 @@ } }, "parse-asn1": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", - "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { "asn1.js": "4.10.1", "browserify-aes": "1.2.0", - "create-hash": "1.1.3", + "create-hash": "1.2.0", "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.14" + "pbkdf2": "3.0.16" } }, "parse-filepath": { @@ -4088,15 +4095,15 @@ "dev": true }, "pbkdf2": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", - "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", + "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", "dev": true, "requires": { - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", "sha.js": "2.4.11" } }, @@ -4198,21 +4205,21 @@ "dev": true }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, "public-encrypt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", - "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", "dev": true, "requires": { "bn.js": "4.11.8", "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "parse-asn1": "5.1.0", + "create-hash": "1.2.0", + "parse-asn1": "5.1.1", "randombytes": "2.0.6" } }, @@ -4278,7 +4285,7 @@ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "randomfill": { @@ -4288,7 +4295,7 @@ "dev": true, "requires": { "randombytes": "2.0.6", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "read-only-stream": { @@ -4297,21 +4304,21 @@ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "requires": { - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, @@ -4325,12 +4332,13 @@ } }, "regex-not": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz", - "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "2.0.1" + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" } }, "remove-bom-buffer": { @@ -4350,7 +4358,7 @@ "dev": true, "requires": { "remove-bom-buffer": "3.0.0", - "safe-buffer": "5.1.1", + "safe-buffer": "5.1.2", "through2": "2.0.3" } }, @@ -4409,6 +4417,12 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -4422,26 +4436,26 @@ "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "7.1.2" } }, "ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "hash-base": "2.0.2", + "hash-base": "3.0.4", "inherits": "2.0.3" } }, "run-sequence": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.1.tgz", - "integrity": "sha1-HOZD2jb9jH6n4akynaM/wriJhJU=", + "integrity": "sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw==", "dev": true, "requires": { "chalk": "1.1.3", @@ -4477,11 +4491,20 @@ } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "0.1.15" + } + }, "sander": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", @@ -4505,7 +4528,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, "semver": { @@ -4520,25 +4543,27 @@ "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", "dev": true }, - "set-getter": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", - "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", - "dev": true, - "requires": { - "to-object-path": "0.3.0" - } - }, "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { "extend-shallow": "2.0.1", "is-extendable": "0.1.1", "is-plain-object": "2.0.4", "split-string": "3.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + } } }, "sha.js": { @@ -4548,7 +4573,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "shasum": { @@ -4580,9 +4605,9 @@ "dev": true }, "snapdragon": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", - "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=", + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { "base": "0.11.2", @@ -4592,7 +4617,7 @@ "map-cache": "0.2.2", "source-map": "0.5.7", "source-map-resolve": "0.5.1", - "use": "2.0.2" + "use": "3.1.0" }, "dependencies": { "define-property": { @@ -4604,80 +4629,72 @@ "is-descriptor": "0.1.6" } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } + "is-extendable": "0.1.1" } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true } } }, "snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { "define-property": "1.0.0", "isobject": "3.0.1", "snapdragon-util": "3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "1.0.2" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "6.0.2" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" + } + } } }, "snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { "kind-of": "3.2.2" @@ -4703,7 +4720,7 @@ "buffer-crc32": "0.2.13", "minimist": "1.2.0", "sander": "0.5.1", - "sourcemap-codec": "1.3.1" + "sourcemap-codec": "1.4.1" } }, "source-map": { @@ -4715,10 +4732,10 @@ "source-map-resolve": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", - "integrity": "sha1-etD1k/IoFZjoVN+A8ZquS5LXoRo=", + "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", "dev": true, "requires": { - "atob": "2.0.3", + "atob": "2.1.0", "decode-uri-component": "0.2.0", "resolve-url": "0.2.1", "source-map-url": "0.4.0", @@ -4726,11 +4743,12 @@ } }, "source-map-support": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.4.tgz", - "integrity": "sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.5.tgz", + "integrity": "sha512-mR7/Nd5l1z6g99010shcXJiNEaf3fEtmLhRB/sBcQVJGodcHCULPp2y4Sfa43Kv2zq7T+Izmfp/WHCR6dYkQCA==", "dev": true, "requires": { + "buffer-from": "1.0.0", "source-map": "0.6.1" }, "dependencies": { @@ -4749,13 +4767,10 @@ "dev": true }, "sourcemap-codec": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.3.1.tgz", - "integrity": "sha1-mtb5vb1pGTEBbjCTnbyGhnMyMUY=", - "dev": true, - "requires": { - "vlq": "0.2.3" - } + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.1.tgz", + "integrity": "sha512-hX1eNBNuilj8yfFnECh0DzLgwKpBLMIvmhgEhixXNui8lMLBInTI8Kyxt++RwJnMNu7cAUo635L2+N1TxMJCzA==", + "dev": true }, "sparkles": { "version": "1.0.0", @@ -4766,31 +4781,10 @@ "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { "extend-shallow": "3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", - "dev": true, - "requires": { - "is-plain-object": "2.0.4" - } - } } }, "sprintf-js": { @@ -4817,63 +4811,6 @@ "requires": { "is-descriptor": "0.1.6" } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true } } }, @@ -4884,7 +4821,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "stream-combiner2": { @@ -4894,13 +4831,13 @@ "dev": true, "requires": { "duplexer2": "0.1.4", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", + "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==", "dev": true }, "stream-http": { @@ -4911,7 +4848,7 @@ "requires": { "builtin-status-codes": "3.0.0", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "to-arraybuffer": "1.0.1", "xtend": "4.0.1" } @@ -4929,7 +4866,7 @@ "dev": true, "requires": { "inherits": "2.0.3", - "readable-stream": "2.3.3" + "readable-stream": "2.3.6" } }, "streamqueue": { @@ -4968,12 +4905,12 @@ } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "strip-ansi": { @@ -5011,9 +4948,9 @@ } }, "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { "has-flag": "3.0.0" @@ -5040,7 +4977,7 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "xtend": "4.0.1" } }, @@ -5125,82 +5062,15 @@ } }, "to-regex": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", - "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "regex-not": "1.0.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true - } + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" } }, "to-regex-range": { @@ -5228,22 +5098,6 @@ "integrity": "sha1-/sAF+dyqJZo/lFnOWmkGq6TFRdo=", "dev": true }, - "ts-node": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-5.0.1.tgz", - "integrity": "sha512-XK7QmDcNHVmZkVtkiwNDWiERRHPyU8nBqZB1+iv2UhOG0q3RQ9HsZ2CMqISlFbxjrYFGfG2mX7bW4dAyxBVzUw==", - "dev": true, - "requires": { - "arrify": "1.0.1", - "chalk": "2.3.2", - "diff": "3.5.0", - "make-error": "1.3.4", - "minimist": "1.2.0", - "mkdirp": "0.5.1", - "source-map-support": "0.5.4", - "yn": "2.0.0" - } - }, "tslib": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", @@ -5258,13 +5112,13 @@ "requires": { "babel-code-frame": "6.26.0", "builtin-modules": "1.1.1", - "chalk": "2.3.2", + "chalk": "2.4.0", "commander": "2.15.1", "diff": "3.5.0", "glob": "7.1.2", - "js-yaml": "3.10.0", + "js-yaml": "3.11.0", "minimatch": "3.0.4", - "resolve": "1.6.0", + "resolve": "1.7.1", "semver": "5.5.0", "tslib": "1.9.0", "tsutils": "2.26.1" @@ -5277,9 +5131,9 @@ "dev": true }, "resolve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", - "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "dev": true, "requires": { "path-parse": "1.0.5" @@ -5318,9 +5172,9 @@ } }, "type-detect": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", - "integrity": "sha1-1w5byB223io4G8rKDG4MvcdjXeI=", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "typedarray": { @@ -5330,9 +5184,9 @@ "dev": true }, "typescript": { - "version": "2.9.0-dev.20180407", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.0-dev.20180407.tgz", - "integrity": "sha512-Tg0/hU2hSz+4pb5Lj5+bj1uLldN7C8NO5Ik19WfftMlpeXRyZQJzglV0oncmsXOfN9gG+JC0xnO58YspE6sZ1w==", + "version": "2.9.0-dev.20180425", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.0-dev.20180425.tgz", + "integrity": "sha512-6t/l13ofVeTSJVD78b20E0rkoOcFPrst5bK9vCGDbbjzx+Ab3HoV7fSTuwB8zMEvpxHwQtR+0kR3XUy06HzwUg==", "dev": true }, "uglify-js": { @@ -5378,6 +5232,15 @@ "set-value": "0.4.3" }, "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "0.1.1" + } + }, "set-value": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", @@ -5463,82 +5326,12 @@ } }, "use": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz", - "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", "dev": true, "requires": { - "define-property": "0.2.5", - "isobject": "3.0.1", - "lazy-cache": "2.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", - "dev": true - } + "kind-of": "6.0.2" } }, "user-home": { @@ -5600,7 +5393,7 @@ "clone": "2.1.2", "clone-buffer": "1.0.0", "clone-stats": "1.0.0", - "cloneable-readable": "1.0.0", + "cloneable-readable": "1.1.2", "remove-trailing-separator": "1.1.0", "replace-ext": "1.0.0" }, @@ -5716,25 +5509,16 @@ } } }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha1-jz5DKM9jsVQMDWfhsneDhviXWyY=", - "dev": true - }, "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.0.1.tgz", + "integrity": "sha512-EqzLchIMYLBjRPoqVsEkZOa/4Vr2RfOWbd58F+I/Gj79AYTrsseMunxbbSkbYfrqZaXSuPBBXNSOhtJgg0PpmA==", + "dev": true }, "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "dev": true, "requires": { "isexe": "2.0.0" @@ -5762,17 +5546,17 @@ "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha1-aGwg8hMgnpSr8NG88e+qKRx4J6c=", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", "dev": true, "requires": { "sax": "1.2.4", - "xmlbuilder": "9.0.4" + "xmlbuilder": "9.0.7" } }, "xmlbuilder": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz", - "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, "xtend": { @@ -5793,12 +5577,6 @@ "decamelize": "1.2.0", "window-size": "0.1.0" } - }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true } } } diff --git a/package.json b/package.json index 71b5ed71029..3e53a3c67b8 100644 --- a/package.json +++ b/package.json @@ -48,11 +48,12 @@ "@types/q": "latest", "@types/run-sequence": "latest", "@types/through2": "latest", + "@types/travis-fold": "latest", "@types/xml2js": "^0.4.0", - "xml2js": "^0.4.19", "browser-resolve": "^1.11.2", "browserify": "latest", "chai": "latest", + "chalk": "latest", "convert-source-map": "latest", "del": "latest", "gulp": "3.X", @@ -77,9 +78,9 @@ "through2": "latest", "travis-fold": "latest", "tslint": "latest", + "typescript": "next", "vinyl": "latest", - "chalk": "latest", - "typescript": "next" + "xml2js": "^0.4.19" }, "scripts": { "pretest": "jake tests", diff --git a/scripts/types/ambient.d.ts b/scripts/types/ambient.d.ts index f99bf010198..4f9112d236e 100644 --- a/scripts/types/ambient.d.ts +++ b/scripts/types/ambient.d.ts @@ -14,4 +14,3 @@ declare module "gulp-insert" { } declare module "sorcery"; -declare module "travis-fold"; From cdfd92b90d21a07e5b7f6947a4ec427f6c88cb9c Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 25 Apr 2018 16:15:49 -0700 Subject: [PATCH 202/229] Don't add import completion from a re-export in "./index" (#23623) * Don't add import completion from a re-export in "./index" * Simpler heuristic --- src/services/codefixes/importFixes.ts | 11 +++++--- .../completionsImport_notFromIndex.ts | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 tests/cases/fourslash/completionsImport_notFromIndex.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index b8694947472..fa466eb8cb9 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -98,16 +98,21 @@ namespace ts.codefix { symbolToken: Node | undefined, preferences: UserPreferences, ): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } { - const exportInfos = getAllReExportingModules(exportedSymbol, symbolName, checker, allSourceFiles); + const exportInfos = getAllReExportingModules(exportedSymbol, moduleSymbol, symbolName, sourceFile, checker, allSourceFiles); Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol)); // We sort the best codefixes first, so taking `first` is best for completions. const moduleSpecifier = first(getNewImportInfos(program, sourceFile, exportInfos, compilerOptions, getCanonicalFileName, host, preferences)).moduleSpecifier; const ctx: ImportCodeFixContext = { host, program, checker, compilerOptions, sourceFile, formatContext, symbolName, getCanonicalFileName, symbolToken, preferences }; return { moduleSpecifier, codeAction: first(getCodeActionsForImport(exportInfos, ctx)) }; } - function getAllReExportingModules(exportedSymbol: Symbol, symbolName: string, checker: TypeChecker, allSourceFiles: ReadonlyArray): ReadonlyArray { + function getAllReExportingModules(exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, sourceFile: SourceFile, checker: TypeChecker, allSourceFiles: ReadonlyArray): ReadonlyArray { const result: SymbolExportInfo[] = []; - forEachExternalModule(checker, allSourceFiles, moduleSymbol => { + forEachExternalModule(checker, allSourceFiles, (moduleSymbol, moduleFile) => { + // Don't import from a re-export when looking "up" like to `./index` or `../index`. + if (moduleFile && moduleSymbol !== exportingModuleSymbol && startsWith(sourceFile.fileName, getDirectoryPath(moduleFile.fileName))) { + return; + } + for (const exported of checker.getExportsOfModule(moduleSymbol)) { if (exported.escapedName === InternalSymbolName.Default || exported.name === symbolName && skipAlias(exported, checker) === exportedSymbol) { const isDefaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol) === exported; diff --git a/tests/cases/fourslash/completionsImport_notFromIndex.ts b/tests/cases/fourslash/completionsImport_notFromIndex.ts new file mode 100644 index 00000000000..c42c768d23d --- /dev/null +++ b/tests/cases/fourslash/completionsImport_notFromIndex.ts @@ -0,0 +1,27 @@ +/// + +// @Filename: /src/a.ts +////export const x = 0; + +// @Filename: /src/index.ts +////export { x } from "./a"; + +// @Filename: /0.ts +////x/*0*/ + +// @Filename: /src/1.ts +////x/*1*/ + +// @Filename: /src/inner/2.ts +////x/*2*/ + +for (const [marker, sourceDisplay] of [["0", "./src"], ["1", "./a"], ["2", "../a"]]) { + goTo.marker(marker); + verify.completionListContains({ name: "x", source: "/src/a" }, "const x: 0", "", "const", /*spanIndex*/ undefined, /*hasAction*/ true, { includeCompletionsForModuleExports: true, sourceDisplay }); + verify.applyCodeActionFromCompletion(marker, { + name: "x", + source: "/src/a", + description: `Import 'x' from module "${sourceDisplay}"`, + newFileContent: `import { x } from "${sourceDisplay}";\n\nx`, + }); +} From d9bc436788c7244a34d0e945a88c7cad0af1ff2a Mon Sep 17 00:00:00 2001 From: Ken703 Date: Wed, 25 Apr 2018 21:10:35 -0400 Subject: [PATCH 203/229] Auto format: no space between closing parenthesis and string template --- src/services/formatting/rules.ts | 3 +++ ...ormatNoSpaceBetweenClosingParenAndTemplateString.ts | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/cases/fourslash/formatNoSpaceBetweenClosingParenAndTemplateString.ts diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 36ea7de23b4..6f15135982b 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -129,6 +129,9 @@ namespace ts.formatting { // template string rule("NoSpaceBetweenTagAndTemplateString", SyntaxKind.Identifier, [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete), + // No space between closing parenthesis and template string + rule("NoSpaceBetweenCloseParenAndTemplateString", SyntaxKind.CloseParenToken, SyntaxKind.NoSubstitutionTemplateLiteral, [isNonJsxSameLineTokenContext], RuleAction.Delete), + // JSX opening elements rule("SpaceBeforeJsxAttribute", anyToken, SyntaxKind.Identifier, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], RuleAction.Space), rule("SpaceBeforeSlashInJsxOpeningElement", anyToken, SyntaxKind.SlashToken, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], RuleAction.Space), diff --git a/tests/cases/fourslash/formatNoSpaceBetweenClosingParenAndTemplateString.ts b/tests/cases/fourslash/formatNoSpaceBetweenClosingParenAndTemplateString.ts new file mode 100644 index 00000000000..47de1fac5d6 --- /dev/null +++ b/tests/cases/fourslash/formatNoSpaceBetweenClosingParenAndTemplateString.ts @@ -0,0 +1,10 @@ +/// + +//// foo() `abc`; +//// bar()`def`; + +format.document(); +verify.currentFileContentIs( +`foo()\`abc\`; +bar()\`def\`;` +); From 096f65c05d07825d32275db7e3c17867bcda8434 Mon Sep 17 00:00:00 2001 From: csigs Date: Thu, 26 Apr 2018 04:10:18 +0000 Subject: [PATCH 204/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5899715db8b..b03397f22a9 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -899,6 +899,9 @@ + + + @@ -1001,6 +1004,9 @@ + + + @@ -6491,6 +6497,12 @@ + + + + + + @@ -8741,6 +8753,12 @@ + + + + + + From aa102435b3b65c1b540464d24a7bd23ea3dfe39f Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 26 Apr 2018 08:00:38 -0700 Subject: [PATCH 205/229] Fix `insertNodeAtClassStart` for empty class with comment (#23342) --- src/compiler/utilities.ts | 6 +- src/services/textChanges.ts | 51 ++++++++-------- .../fourslash/codeFixAddMissingMember.ts | 1 + .../fourslash/codeFixAddMissingMember2.ts | 1 + .../fourslash/codeFixAddMissingMember3.ts | 1 + .../fourslash/codeFixAddMissingMember_all.ts | 1 + .../codeFixAddMissingMember_all_js.ts | 1 + ...odeFixClassExtendAbstractMethod_comment.ts | 24 ++++++++ ...xClassImplementClassMultipleSignatures2.ts | 2 +- ...mentInterfaceTypeParamInstantiateNumber.ts | 2 +- .../codeFixUndeclaredInStaticMethod.ts | 58 +++++++++++++++---- .../fourslash/codeFixUndeclaredMethod.ts | 46 ++++++++++++--- ...efactorConvertToGetAccessAndSetAccess16.ts | 1 + ...efactorConvertToGetAccessAndSetAccess17.ts | 1 + ...efactorConvertToGetAccessAndSetAccess18.ts | 1 + ...efactorConvertToGetAccessAndSetAccess22.ts | 1 + 16 files changed, 152 insertions(+), 46 deletions(-) create mode 100644 tests/cases/fourslash/codeFixClassExtendAbstractMethod_comment.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c5cb19e876a..83cbf16469a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4025,12 +4025,14 @@ namespace ts { } /** Add a value to a set, and return true if it wasn't already present. */ - export function addToSeen(seen: Map, key: string | number): boolean { + export function addToSeen(seen: Map, key: string | number): boolean; + export function addToSeen(seen: Map, key: string | number, value: T): boolean; + export function addToSeen(seen: Map, key: string | number, value: T = true as any): boolean { key = String(key); if (seen.has(key)) { return false; } - seen.set(key, true); + seen.set(key, value); return true; } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 4f431e28e0e..648ab77a922 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -212,8 +212,7 @@ namespace ts.textChanges { export class ChangeTracker { private readonly changes: Change[] = []; private readonly deletedNodesInLists: true[] = []; // Stores ids of nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`. - // Map from class id to nodes to insert at the start - private readonly nodesInsertedAtClassStarts = createMap<{ sourceFile: SourceFile, cls: ClassLikeDeclaration, members: ClassElement[] }>(); + private readonly classesWithNodesInsertedAtStart = createMap(); // Set implemented as Map public static fromContext(context: TextChangesContext): ChangeTracker { return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext); @@ -343,8 +342,7 @@ namespace ts.textChanges { } public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false) { - const pos = getAdjustedStartPosition(sourceFile, before, {}, Position.Start); - return this.replaceRange(sourceFile, { pos, end: pos }, newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween)); + this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}, Position.Start), newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween)); } public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void { @@ -443,21 +441,20 @@ namespace ts.textChanges { } public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration, newElement: ClassElement): void { - const firstMember = firstOrUndefined(cls.members); - if (!firstMember) { - const id = getNodeId(cls).toString(); - const newMembers = this.nodesInsertedAtClassStarts.get(id); - if (newMembers) { - Debug.assert(newMembers.sourceFile === sourceFile && newMembers.cls === cls); - newMembers.members.push(newElement); - } - else { - this.nodesInsertedAtClassStarts.set(id, { sourceFile, cls, members: [newElement] }); + const clsStart = cls.getStart(sourceFile); + let prefix = ""; + let suffix = this.newLineCharacter; + if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), cls)) { + prefix = this.newLineCharacter; + // For `class C {\n}`, don't add the trailing "\n" + if (cls.members.length === 0 && !(positionsAreOnSameLine as any)(...getClassBraceEnds(cls, sourceFile), sourceFile)) { // TODO: GH#4130 remove 'as any' + suffix = ""; } } - else { - this.insertNodeBefore(sourceFile, firstMember, newElement); - } + + const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options) + + this.formatContext.options.indentSize; + this.insertNodeAt(sourceFile, cls.members.pos, newElement, { indentation, prefix, suffix }); } public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node): this { @@ -638,12 +635,14 @@ namespace ts.textChanges { return this; } - private finishInsertNodeAtClassStart(): void { - this.nodesInsertedAtClassStarts.forEach(({ sourceFile, cls, members }) => { - const newCls = cls.kind === SyntaxKind.ClassDeclaration - ? updateClassDeclaration(cls, cls.decorators, cls.modifiers, cls.name, cls.typeParameters, cls.heritageClauses, members) - : updateClassExpression(cls, cls.modifiers, cls.name, cls.typeParameters, cls.heritageClauses, members); - this.replaceNode(sourceFile, cls, newCls); + private finishClassesWithNodesInsertedAtStart(): void { + this.classesWithNodesInsertedAtStart.forEach(cls => { + const sourceFile = cls.getSourceFile(); + const [openBraceEnd, closeBraceEnd] = getClassBraceEnds(cls, sourceFile); + // For `class C { }` remove the whitespace inside the braces. + if (positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) { + this.deleteRange(sourceFile, createTextRange(openBraceEnd, closeBraceEnd - 1)); + } }); } @@ -654,11 +653,15 @@ namespace ts.textChanges { * so we can only call this once and can't get the non-formatted text separately. */ public getChanges(validate?: ValidateNonFormattedText): FileTextChanges[] { - this.finishInsertNodeAtClassStart(); + this.finishClassesWithNodesInsertedAtStart(); return changesToText.getTextChangesFromChanges(this.changes, this.newLineCharacter, this.formatContext, validate); } } + function getClassBraceEnds(cls: ClassLikeDeclaration, sourceFile: SourceFile): [number, number] { + return [findChildOfKind(cls, SyntaxKind.OpenBraceToken, sourceFile).end, findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile).end]; + } + export type ValidateNonFormattedText = (node: Node, text: string) => void; namespace changesToText { diff --git a/tests/cases/fourslash/codeFixAddMissingMember.ts b/tests/cases/fourslash/codeFixAddMissingMember.ts index f5bdf567b20..c507d8b80c9 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember.ts @@ -11,6 +11,7 @@ verify.codeFix({ index: 0, newFileContent: `class C { foo: number; + method() { this.foo = 10; } diff --git a/tests/cases/fourslash/codeFixAddMissingMember2.ts b/tests/cases/fourslash/codeFixAddMissingMember2.ts index a4b7ffb3bfe..b19632dd104 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember2.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember2.ts @@ -11,6 +11,7 @@ verify.codeFix({ index: 1, newFileContent: `class C { [x: string]: number; + method() { this.foo = 10; } diff --git a/tests/cases/fourslash/codeFixAddMissingMember3.ts b/tests/cases/fourslash/codeFixAddMissingMember3.ts index 82512406985..88ea2efef66 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember3.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember3.ts @@ -11,6 +11,7 @@ verify.codeFix({ index: 0, newFileContent: `class C { static foo: number; + static method() { this.foo = 10; } diff --git a/tests/cases/fourslash/codeFixAddMissingMember_all.ts b/tests/cases/fourslash/codeFixAddMissingMember_all.ts index 5a2f8606f2d..0e7abb79cc2 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember_all.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember_all.ts @@ -17,6 +17,7 @@ verify.codeFixAll({ y(): any { throw new Error("Method not implemented."); } + method() { this.x = 0; this.y(); diff --git a/tests/cases/fourslash/codeFixAddMissingMember_all_js.ts b/tests/cases/fourslash/codeFixAddMissingMember_all_js.ts index 5e5a2895fdc..48455943af5 100644 --- a/tests/cases/fourslash/codeFixAddMissingMember_all_js.ts +++ b/tests/cases/fourslash/codeFixAddMissingMember_all_js.ts @@ -21,6 +21,7 @@ verify.codeFixAll({ y() { throw new Error("Method not implemented."); } + constructor() { this.x = undefined; } diff --git a/tests/cases/fourslash/codeFixClassExtendAbstractMethod_comment.ts b/tests/cases/fourslash/codeFixClassExtendAbstractMethod_comment.ts new file mode 100644 index 00000000000..909fd4ba7c7 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassExtendAbstractMethod_comment.ts @@ -0,0 +1,24 @@ +/// + +////abstract class A { +//// abstract m() : void; +////} +//// +////class B extends A { +//// // comment +////} + +verify.codeFix({ + description: "Implement inherited abstract class", + newFileContent: +`abstract class A { + abstract m() : void; +} + +class B extends A { + m(): void { + throw new Error("Method not implemented."); + } + // comment +}`, +}); diff --git a/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures2.ts b/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures2.ts index 4b5be82f870..5da060d3d36 100644 --- a/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures2.ts +++ b/tests/cases/fourslash/codeFixClassImplementClassMultipleSignatures2.ts @@ -6,7 +6,7 @@ //// method(a: string): Function; //// method(a: string | number, b?: string | number): boolean | Function { return a + b as any; } ////} -////class C implements A {[| |]} +////class C implements A { } verify.codeFix({ description: "Implement interface 'A'", diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateNumber.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateNumber.ts index 88f0d32fe18..8bd180907bf 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateNumber.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateNumber.ts @@ -1,7 +1,7 @@ /// ////interface I { x: T; } -////class C implements I {[| |]} +////class C implements I { } verify.codeFix({ description: "Implement interface 'I'", diff --git a/tests/cases/fourslash/codeFixUndeclaredInStaticMethod.ts b/tests/cases/fourslash/codeFixUndeclaredInStaticMethod.ts index cabf3a2d444..f1bac17b2fa 100644 --- a/tests/cases/fourslash/codeFixUndeclaredInStaticMethod.ts +++ b/tests/cases/fourslash/codeFixUndeclaredInStaticMethod.ts @@ -1,7 +1,7 @@ /// -//// class A {[| -//// |]static foo0() { +//// class A { +//// static foo0() { //// this.m1(1,2,3); //// A.m2(1,2); //// this.prop1 = 10; @@ -12,51 +12,89 @@ verify.codeFix({ description: "Declare static method 'm1'", index: 0, - newRangeContent: ` + newFileContent: +`class A { static m1(arg0: any, arg1: any, arg2: any): any { throw new Error("Method not implemented."); } - `, + + static foo0() { + this.m1(1,2,3); + A.m2(1,2); + this.prop1 = 10; + A.prop2 = "asdf"; + } +}`, }); verify.codeFix({ description: "Declare static method 'm2'", index: 0, - newRangeContent: ` + newFileContent: +`class A { static m2(arg0: any, arg1: any): any { throw new Error("Method not implemented."); } + static m1(arg0: any, arg1: any, arg2: any): any { throw new Error("Method not implemented."); } - `, + + static foo0() { + this.m1(1,2,3); + A.m2(1,2); + this.prop1 = 10; + A.prop2 = "asdf"; + } +}`, }); verify.codeFix({ description: "Declare static property 'prop1'", index: 0, - newRangeContent: ` + newFileContent: +`class A { static prop1: number; + static m2(arg0: any, arg1: any): any { throw new Error("Method not implemented."); } + static m1(arg0: any, arg1: any, arg2: any): any { throw new Error("Method not implemented."); } - `, + + static foo0() { + this.m1(1,2,3); + A.m2(1,2); + this.prop1 = 10; + A.prop2 = "asdf"; + } +}`, }); verify.codeFix({ description: "Declare static property 'prop2'", index: 1, // fix at index 0 is to change the spelling to 'prop1' - newRangeContent: ` + newFileContent: +`class A { static prop2: string; + static prop1: number; + static m2(arg0: any, arg1: any): any { throw new Error("Method not implemented."); } + static m1(arg0: any, arg1: any, arg2: any): any { throw new Error("Method not implemented."); } - `, + + static foo0() { + this.m1(1,2,3); + A.m2(1,2); + this.prop1 = 10; + A.prop2 = "asdf"; + } +}`, }); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethod.ts b/tests/cases/fourslash/codeFixUndeclaredMethod.ts index 70ed58b995b..b85e5fbfdfa 100644 --- a/tests/cases/fourslash/codeFixUndeclaredMethod.ts +++ b/tests/cases/fourslash/codeFixUndeclaredMethod.ts @@ -1,7 +1,7 @@ /// -//// class A {[| -//// |]constructor() { +//// class A { +//// constructor() { //// this.foo1(1,2,3); //// // 7 type args //// this.foo2<1,2,3,4,5,6,7>(); @@ -13,38 +13,68 @@ verify.codeFix({ description: "Declare method 'foo1'", index: 0, - newRangeContent: ` + newFileContent: +`class A { foo1(arg0: any, arg1: any, arg2: any): any { throw new Error("Method not implemented."); } - `, + + constructor() { + this.foo1(1,2,3); + // 7 type args + this.foo2<1,2,3,4,5,6,7>(); + // 8 type args + this.foo3<1,2,3,4,5,6,7,8>(); + } +}`, }); verify.codeFix({ description: "Declare method 'foo2'", index: 0, - newRangeContent: ` + newFileContent: +`class A { foo2(): any { throw new Error("Method not implemented."); } + foo1(arg0: any, arg1: any, arg2: any): any { throw new Error("Method not implemented."); } - ` + + constructor() { + this.foo1(1,2,3); + // 7 type args + this.foo2<1,2,3,4,5,6,7>(); + // 8 type args + this.foo3<1,2,3,4,5,6,7,8>(); + } +}` }); verify.codeFix({ description: "Declare method 'foo3'", index: 0, - newRangeContent:` + newFileContent: +`class A { foo3(): any { throw new Error("Method not implemented."); } + foo2(): any { throw new Error("Method not implemented."); } + foo1(arg0: any, arg1: any, arg2: any): any { throw new Error("Method not implemented."); } - ` + + constructor() { + this.foo1(1,2,3); + // 7 type args + this.foo2<1,2,3,4,5,6,7>(); + // 8 type args + this.foo3<1,2,3,4,5,6,7,8>(); + } +}` }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts index dd2cc4cf848..03cadfbceec 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts @@ -17,6 +17,7 @@ edit.applyRefactor({ public set a(value: string) { this._a = value; } + constructor() { } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts index ee212b63502..a04932fe68d 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts @@ -17,6 +17,7 @@ edit.applyRefactor({ protected set a(value: string) { this._a = value; } + constructor() { } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess18.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess18.ts index 37676a8a047..a48361288e0 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess18.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess18.ts @@ -17,6 +17,7 @@ edit.applyRefactor({ public set a(value: string) { this._a = value; } + constructor() { } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess22.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess22.ts index 0c6cd0f9844..d1002c2e809 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess22.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess22.ts @@ -18,6 +18,7 @@ edit.applyRefactor({ public set a(value: string) { this._a = value; } + public a_1: number; constructor() { } }`, From 1541599ea0417ef062c7734c113302d081042a71 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 26 Apr 2018 08:14:22 -0700 Subject: [PATCH 206/229] Check base type for special property declarations (#23671) If the base type has a property by that name, add it to the list constructor types to make it as authoritative as special assignments found in the constructor. --- src/compiler/checker.ts | 25 ++++++++++- ...erringClassMembersFromAssignments3.symbols | 25 +++++++++++ ...nferringClassMembersFromAssignments3.types | 29 +++++++++++++ ...erringClassMembersFromAssignments4.symbols | 28 +++++++++++++ ...nferringClassMembersFromAssignments4.types | 32 ++++++++++++++ ...erringClassMembersFromAssignments5.symbols | 37 ++++++++++++++++ ...nferringClassMembersFromAssignments5.types | 42 +++++++++++++++++++ .../inferringClassMembersFromAssignments3.ts | 16 +++++++ .../inferringClassMembersFromAssignments4.ts | 17 ++++++++ .../inferringClassMembersFromAssignments5.ts | 21 ++++++++++ 10 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/inferringClassMembersFromAssignments3.symbols create mode 100644 tests/baselines/reference/inferringClassMembersFromAssignments3.types create mode 100644 tests/baselines/reference/inferringClassMembersFromAssignments4.symbols create mode 100644 tests/baselines/reference/inferringClassMembersFromAssignments4.types create mode 100644 tests/baselines/reference/inferringClassMembersFromAssignments5.symbols create mode 100644 tests/baselines/reference/inferringClassMembersFromAssignments5.types create mode 100644 tests/cases/conformance/salsa/inferringClassMembersFromAssignments3.ts create mode 100644 tests/cases/conformance/salsa/inferringClassMembersFromAssignments4.ts create mode 100644 tests/cases/conformance/salsa/inferringClassMembersFromAssignments5.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2c4999e516f..fa485b68a92 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4430,7 +4430,7 @@ namespace ts { const special = getSpecialPropertyAssignmentKind(expression); if (special === SpecialPropertyAssignmentKind.ThisProperty) { const thisContainer = getThisContainer(expression, /*includeArrowFunctions*/ false); - // Properties defined in a constructor (or javascript constructor function) don't get undefined added. + // Properties defined in a constructor (or base constructor, or javascript constructor function) don't get undefined added. // Function expressions that are assigned to the prototype count as methods. declarationInConstructor = thisContainer.kind === SyntaxKind.Constructor || thisContainer.kind === SyntaxKind.FunctionDeclaration || @@ -4500,7 +4500,14 @@ namespace ts { } let type = jsDocType; if (!type) { - // use only the constructor types unless only null | undefined (including widening variants) were assigned there + // use only the constructor types unless they were only assigned null | undefined (including widening variants) + if (definedInMethod) { + const propType = getTypeOfSpecialPropertyOfBaseType(symbol); + if (propType) { + (constructorTypes || (constructorTypes = [])).push(propType); + definedInConstructor = true; + } + } const sourceTypes = some(constructorTypes, t => !!(t.flags & ~(TypeFlags.Nullable | TypeFlags.ContainsWideningType))) ? constructorTypes : types; type = getUnionType(sourceTypes, UnionReduction.Subtype); } @@ -4514,6 +4521,20 @@ namespace ts { return widened; } + /** check for definition in base class if any declaration is in a class */ + function getTypeOfSpecialPropertyOfBaseType(specialProperty: Symbol) { + const parentDeclaration = forEach(specialProperty.declarations, d => { + const parent = getThisContainer(d, /*includeArrowFunctions*/ false).parent; + return isClassLike(parent) && parent; + }); + if (parentDeclaration) { + const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(parentDeclaration)) as InterfaceType; + const baseClassType = classType && getBaseTypes(classType)[0]; + if (baseClassType) { + return getTypeOfPropertyOfType(baseClassType, specialProperty.escapedName); + } + } + } // Return the type implied by a binding pattern element. This is the type of the initializer of the element if // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments3.symbols b/tests/baselines/reference/inferringClassMembersFromAssignments3.symbols new file mode 100644 index 00000000000..b4006600dbe --- /dev/null +++ b/tests/baselines/reference/inferringClassMembersFromAssignments3.symbols @@ -0,0 +1,25 @@ +=== tests/cases/conformance/salsa/a.js === +class Base { +>Base : Symbol(Base, Decl(a.js, 0, 0)) + + constructor() { + this.p = 1 +>this.p : Symbol(Base.p, Decl(a.js, 1, 19)) +>this : Symbol(Base, Decl(a.js, 0, 0)) +>p : Symbol(Base.p, Decl(a.js, 1, 19)) + } +} +class Derived extends Base { +>Derived : Symbol(Derived, Decl(a.js, 4, 1)) +>Base : Symbol(Base, Decl(a.js, 0, 0)) + + m() { +>m : Symbol(Derived.m, Decl(a.js, 5, 28)) + + this.p = 1 +>this.p : Symbol(Derived.p, Decl(a.js, 6, 9)) +>this : Symbol(Derived, Decl(a.js, 4, 1)) +>p : Symbol(Derived.p, Decl(a.js, 6, 9)) + } +} + diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments3.types b/tests/baselines/reference/inferringClassMembersFromAssignments3.types new file mode 100644 index 00000000000..60d545b2832 --- /dev/null +++ b/tests/baselines/reference/inferringClassMembersFromAssignments3.types @@ -0,0 +1,29 @@ +=== tests/cases/conformance/salsa/a.js === +class Base { +>Base : Base + + constructor() { + this.p = 1 +>this.p = 1 : 1 +>this.p : number +>this : this +>p : number +>1 : 1 + } +} +class Derived extends Base { +>Derived : Derived +>Base : Base + + m() { +>m : () => void + + this.p = 1 +>this.p = 1 : 1 +>this.p : number +>this : this +>p : number +>1 : 1 + } +} + diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments4.symbols b/tests/baselines/reference/inferringClassMembersFromAssignments4.symbols new file mode 100644 index 00000000000..d0d438c3ed3 --- /dev/null +++ b/tests/baselines/reference/inferringClassMembersFromAssignments4.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/salsa/a.js === +class Base { +>Base : Symbol(Base, Decl(a.js, 0, 0)) + + m() { +>m : Symbol(Base.m, Decl(a.js, 0, 12)) + + this.p = 1 +>this.p : Symbol(Base.p, Decl(a.js, 1, 9)) +>this : Symbol(Base, Decl(a.js, 0, 0)) +>p : Symbol(Base.p, Decl(a.js, 1, 9)) + } +} +class Derived extends Base { +>Derived : Symbol(Derived, Decl(a.js, 4, 1)) +>Base : Symbol(Base, Decl(a.js, 0, 0)) + + m() { +>m : Symbol(Derived.m, Decl(a.js, 5, 28)) + + // should be OK, and p should have type number | undefined from its base + this.p = 1 +>this.p : Symbol(Derived.p, Decl(a.js, 6, 9)) +>this : Symbol(Derived, Decl(a.js, 4, 1)) +>p : Symbol(Derived.p, Decl(a.js, 6, 9)) + } +} + diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments4.types b/tests/baselines/reference/inferringClassMembersFromAssignments4.types new file mode 100644 index 00000000000..f20602d188e --- /dev/null +++ b/tests/baselines/reference/inferringClassMembersFromAssignments4.types @@ -0,0 +1,32 @@ +=== tests/cases/conformance/salsa/a.js === +class Base { +>Base : Base + + m() { +>m : () => void + + this.p = 1 +>this.p = 1 : 1 +>this.p : number | undefined +>this : this +>p : number | undefined +>1 : 1 + } +} +class Derived extends Base { +>Derived : Derived +>Base : Base + + m() { +>m : () => void + + // should be OK, and p should have type number | undefined from its base + this.p = 1 +>this.p = 1 : 1 +>this.p : number | undefined +>this : this +>p : number | undefined +>1 : 1 + } +} + diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments5.symbols b/tests/baselines/reference/inferringClassMembersFromAssignments5.symbols new file mode 100644 index 00000000000..5c46300d770 --- /dev/null +++ b/tests/baselines/reference/inferringClassMembersFromAssignments5.symbols @@ -0,0 +1,37 @@ +=== tests/cases/conformance/salsa/a.js === +class Base { +>Base : Symbol(Base, Decl(a.js, 0, 0)) + + m() { +>m : Symbol(Base.m, Decl(a.js, 0, 12)) + + this.p = 1 +>this.p : Symbol(Base.p, Decl(a.js, 1, 9)) +>this : Symbol(Base, Decl(a.js, 0, 0)) +>p : Symbol(Base.p, Decl(a.js, 1, 9)) + } +} +class Derived extends Base { +>Derived : Symbol(Derived, Decl(a.js, 4, 1)) +>Base : Symbol(Base, Decl(a.js, 0, 0)) + + constructor() { + super(); +>super : Symbol(Base, Decl(a.js, 0, 0)) + + // should be OK, and p should have type number from this assignment + this.p = 1 +>this.p : Symbol(Derived.p, Decl(a.js, 7, 16)) +>this : Symbol(Derived, Decl(a.js, 4, 1)) +>p : Symbol(Derived.p, Decl(a.js, 7, 16)) + } + test() { +>test : Symbol(Derived.test, Decl(a.js, 10, 5)) + + return this.p +>this.p : Symbol(Derived.p, Decl(a.js, 7, 16)) +>this : Symbol(Derived, Decl(a.js, 4, 1)) +>p : Symbol(Derived.p, Decl(a.js, 7, 16)) + } +} + diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments5.types b/tests/baselines/reference/inferringClassMembersFromAssignments5.types new file mode 100644 index 00000000000..fc95b82e5fd --- /dev/null +++ b/tests/baselines/reference/inferringClassMembersFromAssignments5.types @@ -0,0 +1,42 @@ +=== tests/cases/conformance/salsa/a.js === +class Base { +>Base : Base + + m() { +>m : () => void + + this.p = 1 +>this.p = 1 : 1 +>this.p : number | undefined +>this : this +>p : number | undefined +>1 : 1 + } +} +class Derived extends Base { +>Derived : Derived +>Base : Base + + constructor() { + super(); +>super() : void +>super : typeof Base + + // should be OK, and p should have type number from this assignment + this.p = 1 +>this.p = 1 : 1 +>this.p : number +>this : this +>p : number +>1 : 1 + } + test() { +>test : () => number + + return this.p +>this.p : number +>this : this +>p : number + } +} + diff --git a/tests/cases/conformance/salsa/inferringClassMembersFromAssignments3.ts b/tests/cases/conformance/salsa/inferringClassMembersFromAssignments3.ts new file mode 100644 index 00000000000..800bd368dba --- /dev/null +++ b/tests/cases/conformance/salsa/inferringClassMembersFromAssignments3.ts @@ -0,0 +1,16 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @noImplicitAny: true +// @strictNullChecks: true +// @Filename: a.js +class Base { + constructor() { + this.p = 1 + } +} +class Derived extends Base { + m() { + this.p = 1 + } +} diff --git a/tests/cases/conformance/salsa/inferringClassMembersFromAssignments4.ts b/tests/cases/conformance/salsa/inferringClassMembersFromAssignments4.ts new file mode 100644 index 00000000000..ba443bf8595 --- /dev/null +++ b/tests/cases/conformance/salsa/inferringClassMembersFromAssignments4.ts @@ -0,0 +1,17 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @noImplicitAny: true +// @strictNullChecks: true +// @Filename: a.js +class Base { + m() { + this.p = 1 + } +} +class Derived extends Base { + m() { + // should be OK, and p should have type number | undefined from its base + this.p = 1 + } +} diff --git a/tests/cases/conformance/salsa/inferringClassMembersFromAssignments5.ts b/tests/cases/conformance/salsa/inferringClassMembersFromAssignments5.ts new file mode 100644 index 00000000000..5044ea396eb --- /dev/null +++ b/tests/cases/conformance/salsa/inferringClassMembersFromAssignments5.ts @@ -0,0 +1,21 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @noImplicitAny: true +// @strictNullChecks: true +// @Filename: a.js +class Base { + m() { + this.p = 1 + } +} +class Derived extends Base { + constructor() { + super(); + // should be OK, and p should have type number from this assignment + this.p = 1 + } + test() { + return this.p + } +} From 1595f7fe8317ff3055f9bfc55b811039125c3324 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 26 Apr 2018 14:03:18 -0700 Subject: [PATCH 207/229] Add prettier user test and fix associated crash (#23715) * Add prettier and fix crash bug Name resolution would crash when resolving a type name inside a typedef's property tag. * Update tsconfig and thefore prettier baseline --- .gitmodules | 4 + src/compiler/utilities.ts | 8 +- ...docTemplateConstructorFunction2.errors.txt | 13 ++- .../jsdocTemplateConstructorFunction2.symbols | 10 ++ .../jsdocTemplateConstructorFunction2.types | 12 +++ tests/baselines/reference/user/prettier.log | 92 +++++++++++++++++++ .../jsdocTemplateConstructorFunction2.ts | 8 ++ tests/cases/user/prettier/prettier | 1 + tests/cases/user/prettier/test.json | 3 + tests/cases/user/prettier/tsconfig.json | 17 ++++ 10 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/user/prettier.log create mode 160000 tests/cases/user/prettier/prettier create mode 100644 tests/cases/user/prettier/test.json create mode 100644 tests/cases/user/prettier/tsconfig.json diff --git a/.gitmodules b/.gitmodules index fdf474a693d..0e4e0b3ed77 100644 --- a/.gitmodules +++ b/.gitmodules @@ -34,3 +34,7 @@ path = tests/cases/user/axios-src/axios-src url = https://github.com/axios/axios.git ignore = all +[submodule "tests/cases/user/prettier/prettier"] + path = tests/cases/user/prettier/prettier + url = https://github.com/prettier/prettier.git + ignore = all diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 83cbf16469a..04db855d4f8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1889,7 +1889,13 @@ namespace ts { export function getJSDocHost(node: JSDocTag): HasJSDoc { while (node.parent.kind === SyntaxKind.JSDocTypeLiteral) { - node = node.parent.parent.parent as JSDocParameterTag; + if (node.parent.parent.kind === SyntaxKind.JSDocTypedefTag) { + node = node.parent.parent as JSDocTypedefTag; + } + else { + // node.parent.parent is a type expression, child of a parameter type + node = node.parent.parent.parent as JSDocParameterTag; + } } Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment); return node.parent!.parent!; diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt b/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt index db54928b288..6a8e45566ec 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt @@ -1,7 +1,8 @@ tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(21,1): error TS2322: Type 'false' is not assignable to type 'number'. +tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(26,15): error TS2304: Cannot find name 'T'. -==== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js (1 errors) ==== +==== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js (2 errors) ==== /** * @template {T} * @param {T} t @@ -25,4 +26,14 @@ tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(21,1): error T z.u = false ~~~ !!! error TS2322: Type 'false' is not assignable to type 'number'. + + // lookup in typedef should not crash the compiler, even when the type is unknown + /** + * @typedef {Object} A + * @property {T} value + ~ +!!! error TS2304: Cannot find name 'T'. + */ + /** @type {A} */ + const options = { value: null }; \ No newline at end of file diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols index 1913ee53cdf..c65570f84c4 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols @@ -54,3 +54,13 @@ z.u = false >z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3)) >u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) +// lookup in typedef should not crash the compiler, even when the type is unknown +/** + * @typedef {Object} A + * @property {T} value + */ +/** @type {A} */ +const options = { value: null }; +>options : Symbol(options, Decl(templateTagWithNestedTypeLiteral.js, 28, 5)) +>value : Symbol(value, Decl(templateTagWithNestedTypeLiteral.js, 28, 17)) + diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.types b/tests/baselines/reference/jsdocTemplateConstructorFunction2.types index 9f0a55289f3..5737f8caaf9 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.types +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.types @@ -72,3 +72,15 @@ z.u = false >u : number >false : false +// lookup in typedef should not crash the compiler, even when the type is unknown +/** + * @typedef {Object} A + * @property {T} value + */ +/** @type {A} */ +const options = { value: null }; +>options : { value: any; } +>{ value: null } : { value: null; } +>value : null +>null : null + diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log new file mode 100644 index 00000000000..d2c65743131 --- /dev/null +++ b/tests/baselines/reference/user/prettier.log @@ -0,0 +1,92 @@ +Exit Code: 1 +Standard output: +index.js(3,25): error TS2307: Cannot find module './package.json'. +index.js(138,21): error TS2532: Object is possibly 'undefined'. +src/cli/util.js(262,64): error TS2339: Property 'length' does not exist on type 'Ignore'. +src/cli/util.js(335,52): error TS2339: Property 'length' does not exist on type 'Ignore'. +src/cli/util.js(396,46): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number | undefined'. +src/cli/util.js(403,39): error TS2339: Property 'grey' does not exist on type 'typeof import("/home/nathansa/ts/node_modules/chalk/types/index")'. +src/common/parser-create-error.js(8,9): error TS2339: Property 'loc' does not exist on type 'SyntaxError'. +src/config/resolve-config.js(75,32): error TS2345: Argument of type '{ sync: false; }' is not assignable to parameter of type '{ cache: boolean; sync: boolean; }'. + Property 'cache' is missing in type '{ sync: false; }'. +src/config/resolve-config.js(82,32): error TS2345: Argument of type '{ sync: true; }' is not assignable to parameter of type '{ cache: boolean; sync: boolean; }'. + Property 'cache' is missing in type '{ sync: true; }'. +src/doc/doc-printer.js(213,17): error TS2532: Object is possibly 'undefined'. +src/doc/doc-printer.js(214,18): error TS2532: Object is possibly 'undefined'. +src/doc/doc-printer.js(215,17): error TS2532: Object is possibly 'undefined'. +src/language-css/clean.js(3,30): error TS2307: Cannot find module 'html-tag-names'. +src/language-css/parser-postcss.js(78,32): error TS2345: Argument of type '{ [x: string]: any; groups: never[]; type: string; }' is not assignable to parameter of type 'never'. +src/language-css/parser-postcss.js(88,30): error TS2345: Argument of type '{ [x: string]: any; open: null; close: null; groups: never[]; type: string; }' is not assignable to parameter of type 'never'. +src/language-css/parser-postcss.js(93,30): error TS2345: Argument of type '{ [x: string]: any; groups: never[]; type: string; }' is not assignable to parameter of type 'never'. +src/language-css/parser-postcss.js(100,30): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. +src/language-css/parser-postcss.js(104,28): error TS2345: Argument of type '{ [x: string]: any; groups: never[]; type: string; }' is not assignable to parameter of type 'never'. +src/language-css/parser-postcss.js(407,32): error TS2531: Object is possibly 'null'. +src/language-css/printer-postcss.js(3,30): error TS2307: Cannot find module 'html-tag-names'. +src/language-handlebars/parser-glimmer.js(27,26): error TS2345: Argument of type '{ plugins: { ast: (() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): voi...' is not assignable to parameter of type 'PreprocessOptions | undefined'. + Type '{ plugins: { ast: (() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): voi...' is not assignable to type 'PreprocessOptions'. + Types of property 'plugins' are incompatible. + Type '{ ast: (() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementN...' is not assignable to type '{ ast?: ASTPluginBuilder[] | undefined; } | undefined'. + Type '{ ast: (() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementN...' is not assignable to type '{ ast?: ASTPluginBuilder[] | undefined; }'. + Types of property 'ast' are incompatible. + Type '(() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(nod...' is not assignable to type 'ASTPluginBuilder[] | undefined'. + Type '(() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(nod...' is not assignable to type 'ASTPluginBuilder[]'. + Type '() => { [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(node...' is not assignable to type 'ASTPluginBuilder'. + Type '{ [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(node: any)...' is not assignable to type 'ASTPlugin'. + Property 'name' is missing in type '{ [x: string]: any; visitor: { [x: string]: any; Program(node: any): void; ElementNode(node: any)...'. +src/language-handlebars/printer-glimmer.js(270,7): error TS2554: Expected 0-1 arguments, but got 2. +src/language-js/printer-estree.js(99,9): error TS2322: Type '{ [x: string]: any; type: string; }' is not assignable to type '{ [x: string]: any; type: string; parts: any; }'. + Property 'parts' is missing in type '{ [x: string]: any; type: string; }'. +src/language-js/printer-estree.js(302,9): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; } | { [x: string]: any; type: string; contents: any...' is not assignable to parameter of type 'ConcatArray'. + Type '{ [x: string]: any; type: string; parts: any; }' is not assignable to type 'ConcatArray'. + Property 'length' is missing in type '{ [x: string]: any; type: string; parts: any; }'. +src/language-js/printer-estree.js(1224,28): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; }' is not assignable to parameter of type 'string | ConcatArray'. + Type '{ [x: string]: any; type: string; parts: any; }' is not assignable to type 'ConcatArray'. + Property 'length' is missing in type '{ [x: string]: any; type: string; parts: any; }'. +src/language-js/printer-estree.js(1601,20): error TS2345: Argument of type '" "' is not assignable to parameter of type '{ [x: string]: any; type: string; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(1603,20): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; }' is not assignable to parameter of type '{ [x: string]: any; type: string; contents: any; break: boolean; expandedStates: any; }'. + Property 'contents' is missing in type '{ [x: string]: any; type: string; parts: any; }'. +src/language-js/printer-estree.js(1605,18): error TS2345: Argument of type '"while ("' is not assignable to parameter of type '{ [x: string]: any; type: string; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(1614,9): error TS2345: Argument of type '")"' is not assignable to parameter of type '{ [x: string]: any; type: string; contents: any; break: boolean; expandedStates: any; }'. +src/language-js/printer-estree.js(3293,23): error TS2532: Object is possibly 'undefined'. +src/language-js/printer-estree.js(3294,24): error TS2532: Object is possibly 'undefined'. +src/language-js/printer-estree.js(3647,5): error TS2345: Argument of type '"" | { [x: string]: any; type: string; parts: any; } | { [x: string]: any; type: string; contents...' is not assignable to parameter of type 'string'. + Type '{ [x: string]: any; type: string; parts: any; }' is not assignable to type 'string'. +src/language-js/printer-estree.js(3651,16): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(3693,9): error TS2345: Argument of type '{ [x: string]: any; type: string; parts: any; }' is not assignable to parameter of type 'string'. +src/language-js/printer-estree.js(3995,14): error TS2554: Expected 0-2 arguments, but got 3. +src/language-js/printer-estree.js(5034,9): error TS2554: Expected 0-1 arguments, but got 2. +src/language-js/printer-estree.js(5070,7): error TS2345: Argument of type '(string | number)[]' is not assignable to parameter of type '((childPath: any) => any) | ConcatArray<(childPath: any) => any>'. + Type '(string | number)[]' is not assignable to type 'ConcatArray<(childPath: any) => any>'. + Types of property 'slice' are incompatible. + Type '(start?: number | undefined, end?: number | undefined) => (string | number)[]' is not assignable to type '(start?: number | undefined, end?: number | undefined) => ((childPath: any) => any)[]'. + Type '(string | number)[]' is not assignable to type '((childPath: any) => any)[]'. + Type 'string | number' is not assignable to type '(childPath: any) => any'. + Type 'string' is not assignable to type '(childPath: any) => any'. +src/language-markdown/printer-markdown.js(258,18): error TS2532: Object is possibly 'undefined'. +src/language-markdown/printer-markdown.js(259,17): error TS2532: Object is possibly 'undefined'. +src/language-markdown/printer-markdown.js(283,14): error TS2532: Object is possibly 'undefined'. +src/language-vue/parser-vue.js(54,23): error TS2345: Argument of type '(m: string, g: any) => void' is not assignable to parameter of type '(substring: string, ...args: any[]) => string'. + Type 'void' is not assignable to type 'string'. +src/language-vue/parser-vue.js(180,34): error TS2339: Property 'toLowerCase' does not exist on type 'never'. +src/language-vue/parser-vue.js(244,26): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. +src/language-vue/parser-vue.js(393,25): error TS2345: Argument of type '{ [x: string]: any; tag: any; attrs: any; unary: any; start: any; children: never[]; }' is not assignable to parameter of type 'never'. +src/language-vue/parser-vue.js(398,23): error TS2345: Argument of type '{ [x: string]: any; tag: any; attrs: any; unary: any; start: any; children: never[]; }' is not assignable to parameter of type '{ [x: string]: any; tag: string; attrs: never[]; unary: boolean; start: number; contentStart: num...'. + Property 'contentStart' is missing in type '{ [x: string]: any; tag: any; attrs: any; unary: any; start: any; children: never[]; }'. +src/language-vue/parser-vue.js(399,9): error TS2322: Type '{ [x: string]: any; tag: any; attrs: any; unary: any; start: any; children: never[]; }' is not assignable to type '{ [x: string]: any; tag: string; attrs: never[]; unary: boolean; start: number; contentStart: num...'. +src/main/core-options.js(51,43): error TS1005: '}' expected. +src/main/core-options.js(63,5): error TS2322: Type '{ cursorOffset: { since: string; category: string; type: "int"; default: number; range: { start: ...' is not assignable to type '{ [name: string]: { since: string; category: string; type: "boolean" | "path" | "int" | "choice";...'. + Property 'cursorOffset' is incompatible with index signature. + Type '{ since: string; category: string; type: "int"; default: number; range: { start: number; end: num...' is not assignable to type '{ since: string; category: string; type: "boolean" | "path" | "int" | "choice"; array: boolean; d...'. + Object literal may only specify known properties, and 'cliCategory' does not exist in type '{ since: string; category: string; type: "boolean" | "path" | "int" | "choice"; array: boolean; d...'. +src/main/parser.js(61,9): error TS2345: Argument of type 'PropertyDescriptor | undefined' is not assignable to parameter of type 'PropertyDescriptor & ThisType'. + Type 'undefined' is not assignable to type 'PropertyDescriptor & ThisType'. + Type 'undefined' is not assignable to type 'PropertyDescriptor'. +src/main/support.js(5,32): error TS2307: Cannot find module '../../package.json'. +src/main/support.js(36,24): error TS2339: Property 'name' does not exist on type 'never'. +src/main/support.js(36,35): error TS2339: Property 'name' does not exist on type 'never'. +src/main/support.js(36,48): error TS2339: Property 'name' does not exist on type 'never'. +src/main/support.js(36,57): error TS2339: Property 'name' does not exist on type 'never'. + + + +Standard error: diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts index 750126a05b9..a4f107190ff 100644 --- a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts +++ b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts @@ -24,3 +24,11 @@ Zet.prototype.add = function(v, o) { var z = new Zet(1) z.t = 2 z.u = false + +// lookup in typedef should not crash the compiler, even when the type is unknown +/** + * @typedef {Object} A + * @property {T} value + */ +/** @type {A} */ +const options = { value: null }; diff --git a/tests/cases/user/prettier/prettier b/tests/cases/user/prettier/prettier new file mode 160000 index 00000000000..67f1c4877ee --- /dev/null +++ b/tests/cases/user/prettier/prettier @@ -0,0 +1 @@ +Subproject commit 67f1c4877ee1090b66d468a847caccca411a6f82 diff --git a/tests/cases/user/prettier/test.json b/tests/cases/user/prettier/test.json new file mode 100644 index 00000000000..b6495a1b80b --- /dev/null +++ b/tests/cases/user/prettier/test.json @@ -0,0 +1,3 @@ +{ + "types": ["node"] +} diff --git a/tests/cases/user/prettier/tsconfig.json b/tests/cases/user/prettier/tsconfig.json new file mode 100644 index 00000000000..d3b1f270dbc --- /dev/null +++ b/tests/cases/user/prettier/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "noImplicitAny": false, + "noImplicitThis": false, + "maxNodeModuleJsDepth": 0, + "strict": true, + "noEmit": true, + "allowJs": true, + "checkJs": true, + "types": ["node"], + "lib": ["esnext", "dom"], + "target": "esnext", + "module": "commonjs", + "pretty": false, + }, + "include": ["prettier/src"] +} From bcb5599bf2a1f0db0592f3b680e303f8884ffad0 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 26 Apr 2018 16:18:47 -0700 Subject: [PATCH 208/229] Fix typo (#23725) --- src/services/types.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/types.ts b/src/services/types.ts index e835d0cdef6..2369db8a0ce 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -331,7 +331,7 @@ namespace ts { applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; /** @deprecated `fileName` will be ignored */ applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; - getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; + getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 504d0c18d40..5e09f5aa951 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4451,7 +4451,7 @@ declare namespace ts { applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; /** @deprecated `fileName` will be ignored */ applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; - getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; + getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 967fe44aab6..9d87ec68d43 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4451,7 +4451,7 @@ declare namespace ts { applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise; /** @deprecated `fileName` will be ignored */ applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise; - getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; + getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; From d25a6ec9ad10049d407407e07859ca4f09873a77 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 27 Apr 2018 10:40:16 -0700 Subject: [PATCH 209/229] Remove redundant primitive types from intersections with literal types --- src/compiler/checker.ts | 146 +++++++++++++++++++--------------------- src/compiler/types.ts | 8 +++ 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f3be433aec1..374e27f9e77 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -617,22 +617,6 @@ namespace ts { Both = Source | Target, } - const enum TypeIncludes { - Any = 1 << 0, - Undefined = 1 << 1, - Null = 1 << 2, - Never = 1 << 3, - NonWideningType = 1 << 4, - String = 1 << 5, - Number = 1 << 6, - ESSymbol = 1 << 7, - LiteralOrUniqueESSymbol = 1 << 8, - ObjectType = 1 << 9, - EmptyObject = 1 << 10, - Union = 1 << 11, - Wildcard = 1 << 12, - } - const enum MembersOrExportsResolutionKind { resolvedExports = "resolvedExports", resolvedMembers = "resolvedMembers" @@ -7926,35 +7910,31 @@ namespace ts { return false; } - function addTypeToUnion(typeSet: Type[], includes: TypeIncludes, type: Type) { + function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) { const flags = type.flags; if (flags & TypeFlags.Union) { - includes = addTypesToUnion(typeSet, includes, (type).types); + return addTypesToUnion(typeSet, includes, (type).types); } - else if (flags & TypeFlags.Any) { - includes |= TypeIncludes.Any; - if (type === wildcardType) includes |= TypeIncludes.Wildcard; - } - else if (!strictNullChecks && flags & TypeFlags.Nullable) { - if (flags & TypeFlags.Undefined) includes |= TypeIncludes.Undefined; - if (flags & TypeFlags.Null) includes |= TypeIncludes.Null; - if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeIncludes.NonWideningType; - } - else if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(type))) { - // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are - // another form of 'never' (in that they have an empty value domain). We could in theory turn - // intersections of unit types into 'never' upon construction, but deferring the reduction makes it - // easier to reason about their origin. - if (flags & TypeFlags.String) includes |= TypeIncludes.String; - if (flags & TypeFlags.Number) includes |= TypeIncludes.Number; - if (flags & TypeFlags.ESSymbol) includes |= TypeIncludes.ESSymbol; - if (flags & TypeFlags.StringOrNumberLiteralOrUnique) includes |= TypeIncludes.LiteralOrUniqueESSymbol; - const len = typeSet.length; - const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); - if (index < 0) { - if (!(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && - type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) { - typeSet.splice(~index, 0, type); + // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are + // another form of 'never' (in that they have an empty value domain). We could in theory turn + // intersections of unit types into 'never' upon construction, but deferring the reduction makes it + // easier to reason about their origin. + if (!(flags & TypeFlags.Never || flags & TypeFlags.Intersection && isEmptyIntersectionType(type))) { + includes |= flags & ~TypeFlags.ConstructionFlags; + if (flags & TypeFlags.Any) { + if (type === wildcardType) includes |= TypeFlags.Wildcard; + } + else if (!strictNullChecks && flags & TypeFlags.Nullable) { + if (!(flags & TypeFlags.ContainsWideningType)) includes |= TypeFlags.NonWideningType; + } + else { + const len = typeSet.length; + const index = len && type.id > typeSet[len - 1].id ? ~len : binarySearch(typeSet, type, getTypeId, compareValues); + if (index < 0) { + if (!(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && + type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) { + typeSet.splice(~index, 0, type); + } } } } @@ -7963,7 +7943,7 @@ namespace ts { // Add the given types to the given type set. Order is preserved, duplicates are removed, // and nested types of the given kind are flattened into the set. - function addTypesToUnion(typeSet: Type[], includes: TypeIncludes, types: Type[]): TypeIncludes { + function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: Type[]): TypeFlags { for (const type of types) { includes = addTypeToUnion(typeSet, includes, type); } @@ -8020,15 +8000,15 @@ namespace ts { } } - function removeRedundantLiteralTypes(types: Type[], includes: TypeIncludes) { + function removeRedundantLiteralTypes(types: Type[], includes: TypeFlags) { let i = types.length; while (i > 0) { i--; const t = types[i]; const remove = - t.flags & TypeFlags.StringLiteral && includes & TypeIncludes.String || - t.flags & TypeFlags.NumberLiteral && includes & TypeIncludes.Number || - t.flags & TypeFlags.UniqueESSymbol && includes & TypeIncludes.ESSymbol || + t.flags & TypeFlags.StringLiteral && includes & TypeFlags.String || + t.flags & TypeFlags.NumberLiteral && includes & TypeFlags.Number || + t.flags & TypeFlags.UniqueESSymbol && includes & TypeFlags.ESSymbol || t.flags & TypeFlags.StringOrNumberLiteral && t.flags & TypeFlags.FreshLiteral && containsType(types, (t).regularType); if (remove) { orderedRemoveItemAt(types, i); @@ -8052,12 +8032,12 @@ namespace ts { } const typeSet: Type[] = []; const includes = addTypesToUnion(typeSet, 0, types); - if (includes & TypeIncludes.Any) { - return includes & TypeIncludes.Wildcard ? wildcardType : anyType; + if (includes & TypeFlags.Any) { + return includes & TypeFlags.Wildcard ? wildcardType : anyType; } switch (unionReduction) { case UnionReduction.Literal: - if (includes & TypeIncludes.LiteralOrUniqueESSymbol) { + if (includes & TypeFlags.StringOrNumberLiteralOrUnique) { removeRedundantLiteralTypes(typeSet, includes); } break; @@ -8066,8 +8046,8 @@ namespace ts { break; } if (typeSet.length === 0) { - return includes & TypeIncludes.Null ? includes & TypeIncludes.NonWideningType ? nullType : nullWideningType : - includes & TypeIncludes.Undefined ? includes & TypeIncludes.NonWideningType ? undefinedType : undefinedWideningType : + return includes & TypeFlags.Null ? includes & TypeFlags.NonWideningType ? nullType : nullWideningType : + includes & TypeFlags.Undefined ? includes & TypeFlags.NonWideningType ? undefinedType : undefinedWideningType : neverType; } return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments); @@ -8145,30 +8125,23 @@ namespace ts { return links.resolvedType; } - function addTypeToIntersection(typeSet: Type[], includes: TypeIncludes, type: Type) { + function addTypeToIntersection(typeSet: Type[], includes: TypeFlags, type: Type) { const flags = type.flags; if (flags & TypeFlags.Intersection) { - includes = addTypesToIntersection(typeSet, includes, (type).types); + return addTypesToIntersection(typeSet, includes, (type).types); } - else if (flags & TypeFlags.Any) { - includes |= TypeIncludes.Any; - if (type === wildcardType) includes |= TypeIncludes.Wildcard; + if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) { + includes |= TypeFlags.EmptyObject; } - else if (flags & TypeFlags.Never) { - includes |= TypeIncludes.Never; - } - else if (getObjectFlags(type) & ObjectFlags.Anonymous && isEmptyObjectType(type)) { - includes |= TypeIncludes.EmptyObject; - } - else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type)) { - if (flags & TypeFlags.Object) { - includes |= TypeIncludes.ObjectType; + else { + includes |= flags & ~TypeFlags.ConstructionFlags; + if (flags & TypeFlags.Any) { + if (type === wildcardType) includes |= TypeFlags.Wildcard; } - if (flags & TypeFlags.Union) { - includes |= TypeIncludes.Union; - } - if (!(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && - type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && containsIdenticalType(typeSet, type))) { + else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type) && + !(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && + type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && + containsIdenticalType(typeSet, type))) { typeSet.push(type); } } @@ -8177,13 +8150,27 @@ namespace ts { // Add the given types to the given type set. Order is preserved, freshness is removed from literal // types, duplicates are removed, and nested types of the given kind are flattened into the set. - function addTypesToIntersection(typeSet: Type[], includes: TypeIncludes, types: Type[]) { + function addTypesToIntersection(typeSet: Type[], includes: TypeFlags, types: Type[]) { for (const type of types) { includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type)); } return includes; } + function removeRedundantPrimtiveTypes(types: Type[], includes: TypeFlags) { + let i = types.length; + while (i > 0) { + i--; + const t = types[i]; + const remove = + t.flags & TypeFlags.String && includes & TypeFlags.StringLiteral || + t.flags & TypeFlags.Number && includes & TypeFlags.NumberLiteral || + t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol; + if (remove) { + orderedRemoveItemAt(types, i); + } + } + } // We normalize combinations of intersection and union types based on the distributive property of the '&' // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection // types with union type constituents into equivalent union types with intersection type constituents and @@ -8200,19 +8187,24 @@ namespace ts { } const typeSet: Type[] = []; const includes = addTypesToIntersection(typeSet, 0, types); - if (includes & TypeIncludes.Never) { + if (includes & TypeFlags.Never) { return neverType; } - if (includes & TypeIncludes.Any) { - return includes & TypeIncludes.Wildcard ? wildcardType : anyType; + if (includes & TypeFlags.Any) { + return includes & TypeFlags.Wildcard ? wildcardType : anyType; } - if (includes & TypeIncludes.EmptyObject && !(includes & TypeIncludes.ObjectType)) { + if (includes & TypeFlags.String && includes & TypeFlags.StringLiteral || + includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral || + includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) { + removeRedundantPrimtiveTypes(typeSet, includes); + } + if (includes & TypeFlags.EmptyObject && !(includes & TypeFlags.Object)) { typeSet.push(emptyObjectType); } if (typeSet.length === 1) { return typeSet[0]; } - if (includes & TypeIncludes.Union) { + if (includes & TypeFlags.Union) { // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain. const unionIndex = findIndex(typeSet, t => (t.flags & TypeFlags.Union) !== 0); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 2aea2e29742..c0d9b0ed9af 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3636,7 +3636,15 @@ namespace ts { RequiresWidening = ContainsWideningType | ContainsObjectLiteral, /* @internal */ PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType, + // The following flags are used for different purposes during union and intersection type construction /* @internal */ + NonWideningType = ContainsWideningType, + /* @internal */ + Wildcard = ContainsObjectLiteral, + /* @internal */ + EmptyObject = ContainsAnyFunctionType, + /* @internal */ + ConstructionFlags = NonWideningType | Wildcard | EmptyObject } export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; From d5ef1174bd500ee919be05e75ddf10eb70009190 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 27 Apr 2018 13:12:35 -0700 Subject: [PATCH 210/229] Copy consistient valueDeclarations on union/intersection symbols (#23190) --- src/compiler/checker.ts | 16 ++++++- ...oubleMixinConditionalTypeBaseClassWorks.js | 42 +++++++++++++++++++ ...MixinConditionalTypeBaseClassWorks.symbols | 36 ++++++++++++++++ ...leMixinConditionalTypeBaseClassWorks.types | 42 +++++++++++++++++++ ...oubleMixinConditionalTypeBaseClassWorks.ts | 8 ++++ 5 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.js create mode 100644 tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.symbols create mode 100644 tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.types create mode 100644 tests/cases/compiler/doubleMixinConditionalTypeBaseClassWorks.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fa485b68a92..0819ece651e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6677,7 +6677,15 @@ namespace ts { let nameType: Type; const propTypes: Type[] = []; let first = true; + let commonValueDeclaration: Declaration; + let hasNonUniformValueDeclaration = false; for (const prop of props) { + if (!commonValueDeclaration) { + commonValueDeclaration = prop.valueDeclaration; + } + else if (prop.valueDeclaration !== commonValueDeclaration) { + hasNonUniformValueDeclaration = true; + } declarations = addRange(declarations, prop.declarations); const type = getTypeOfSymbol(prop); if (first) { @@ -6694,6 +6702,9 @@ namespace ts { } const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags); result.containingType = containingType; + if (!hasNonUniformValueDeclaration && commonValueDeclaration) { + result.valueDeclaration = commonValueDeclaration; + } result.declarations = declarations; result.nameType = nameType; result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes); @@ -10774,13 +10785,14 @@ namespace ts { const sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp); const targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp); if (sourcePropFlags & ModifierFlags.Private || targetPropFlags & ModifierFlags.Private) { - if (getCheckFlags(sourceProp) & CheckFlags.ContainsPrivate) { + const hasDifferingDeclarations = sourceProp.valueDeclaration !== targetProp.valueDeclaration; + if (getCheckFlags(sourceProp) & CheckFlags.ContainsPrivate && hasDifferingDeclarations) { if (reportErrors) { reportError(Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), typeToString(source)); } return Ternary.False; } - if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) { + if (hasDifferingDeclarations) { if (reportErrors) { if (sourcePropFlags & ModifierFlags.Private && targetPropFlags & ModifierFlags.Private) { reportError(Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp)); diff --git a/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.js b/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.js new file mode 100644 index 00000000000..6ea7a46bb68 --- /dev/null +++ b/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.js @@ -0,0 +1,42 @@ +//// [doubleMixinConditionalTypeBaseClassWorks.ts] +type Constructor = new (...args: any[]) => {}; + +const Mixin1 = (Base: C) => class extends Base { private _fooPrivate: {}; } + +type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never; +const Mixin2 = (Base: C) => class extends Base {}; + +class C extends Mixin2(Mixin1(Object)) {} + +//// [doubleMixinConditionalTypeBaseClassWorks.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var Mixin1 = function (Base) { return /** @class */ (function (_super) { + __extends(class_1, _super); + function class_1() { + return _super !== null && _super.apply(this, arguments) || this; + } + return class_1; +}(Base)); }; +var Mixin2 = function (Base) { return /** @class */ (function (_super) { + __extends(class_2, _super); + function class_2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return class_2; +}(Base)); }; +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C; +}(Mixin2(Mixin1(Object)))); diff --git a/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.symbols b/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.symbols new file mode 100644 index 00000000000..f1f0187a7eb --- /dev/null +++ b/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.symbols @@ -0,0 +1,36 @@ +=== tests/cases/compiler/doubleMixinConditionalTypeBaseClassWorks.ts === +type Constructor = new (...args: any[]) => {}; +>Constructor : Symbol(Constructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 0, 0)) +>args : Symbol(args, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 0, 24)) + +const Mixin1 = (Base: C) => class extends Base { private _fooPrivate: {}; } +>Mixin1 : Symbol(Mixin1, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 5)) +>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 16)) +>Constructor : Symbol(Constructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 0, 0)) +>Base : Symbol(Base, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 39)) +>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 16)) +>Base : Symbol(Base, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 39)) +>_fooPrivate : Symbol((Anonymous class)._fooPrivate, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 71)) + +type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never; +>FooConstructor : Symbol(FooConstructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 98)) +>Mixin1 : Symbol(Mixin1, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 5)) +>a : Symbol(a, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 4, 45)) +>Constructor : Symbol(Constructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 0, 0)) +>Cls : Symbol(Cls, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 4, 69)) +>Cls : Symbol(Cls, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 4, 69)) + +const Mixin2 = (Base: C) => class extends Base {}; +>Mixin2 : Symbol(Mixin2, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 5)) +>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 16)) +>FooConstructor : Symbol(FooConstructor, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 98)) +>Base : Symbol(Base, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 42)) +>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 16)) +>Base : Symbol(Base, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 42)) + +class C extends Mixin2(Mixin1(Object)) {} +>C : Symbol(C, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 76)) +>Mixin2 : Symbol(Mixin2, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 5, 5)) +>Mixin1 : Symbol(Mixin1, Decl(doubleMixinConditionalTypeBaseClassWorks.ts, 2, 5)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + diff --git a/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.types b/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.types new file mode 100644 index 00000000000..5fd92f6e2eb --- /dev/null +++ b/tests/baselines/reference/doubleMixinConditionalTypeBaseClassWorks.types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/doubleMixinConditionalTypeBaseClassWorks.ts === +type Constructor = new (...args: any[]) => {}; +>Constructor : Constructor +>args : any[] + +const Mixin1 = (Base: C) => class extends Base { private _fooPrivate: {}; } +>Mixin1 : (Base: C) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>(Base: C) => class extends Base { private _fooPrivate: {}; } : (Base: C) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>C : C +>Constructor : Constructor +>Base : C +>C : C +>class extends Base { private _fooPrivate: {}; } : { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>Base : {} +>_fooPrivate : {} + +type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never; +>FooConstructor : { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); } & Constructor +>Mixin1 : (Base: C) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>a : Constructor +>Constructor : Constructor +>Cls : Cls +>Cls : Cls + +const Mixin2 = (Base: C) => class extends Base {}; +>Mixin2 : .(Anonymous class); prototype: .(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>(Base: C) => class extends Base {} : .(Anonymous class); prototype: .(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>C : C +>FooConstructor : { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); } & Constructor +>Base : C +>C : C +>class extends Base {} : { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>Base : .(Anonymous class) + +class C extends Mixin2(Mixin1(Object)) {} +>C : C +>Mixin2(Mixin1(Object)) : <{ new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); } & ObjectConstructor>.(Anonymous class) & .(Anonymous class) & Object +>Mixin2 : .(Anonymous class); prototype: .(Anonymous class); } & Constructor>(Base: C) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>Mixin1(Object) : { new (...args: any[]): .(Anonymous class); prototype: .(Anonymous class); } & ObjectConstructor +>Mixin1 : (Base: C) => { new (...args: any[]): (Anonymous class); prototype: .(Anonymous class); } & C +>Object : ObjectConstructor + diff --git a/tests/cases/compiler/doubleMixinConditionalTypeBaseClassWorks.ts b/tests/cases/compiler/doubleMixinConditionalTypeBaseClassWorks.ts new file mode 100644 index 00000000000..616e5f56b3f --- /dev/null +++ b/tests/cases/compiler/doubleMixinConditionalTypeBaseClassWorks.ts @@ -0,0 +1,8 @@ +type Constructor = new (...args: any[]) => {}; + +const Mixin1 = (Base: C) => class extends Base { private _fooPrivate: {}; } + +type FooConstructor = typeof Mixin1 extends (a: Constructor) => infer Cls ? Cls : never; +const Mixin2 = (Base: C) => class extends Base {}; + +class C extends Mixin2(Mixin1(Object)) {} \ No newline at end of file From 3631af6486b91bd01d62fc346dd1e8cf39683b77 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 27 Apr 2018 14:54:59 -0700 Subject: [PATCH 211/229] Remove readonly from object rest properties (#23746) * Remove readonly from object rest properties Works the same as removing it from object spread properties * Fix bug number in test --- src/compiler/checker.ts | 2 +- .../baselines/reference/objectRestReadonly.js | 36 +++++++++++++++ .../reference/objectRestReadonly.symbols | 40 +++++++++++++++++ .../reference/objectRestReadonly.types | 45 +++++++++++++++++++ .../types/rest/objectRestReadonly.ts | 16 +++++++ 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/objectRestReadonly.js create mode 100644 tests/baselines/reference/objectRestReadonly.symbols create mode 100644 tests/baselines/reference/objectRestReadonly.types create mode 100644 tests/cases/conformance/types/rest/objectRestReadonly.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0819ece651e..018539b1b0e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4180,7 +4180,7 @@ namespace ts { const isPrivate = getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected); const isSetOnlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) { - members.set(prop.escapedName, prop); + members.set(prop.escapedName, getNonReadonlySymbol(prop)); } } const stringIndexInfo = getIndexInfoOfType(source, IndexKind.String); diff --git a/tests/baselines/reference/objectRestReadonly.js b/tests/baselines/reference/objectRestReadonly.js new file mode 100644 index 00000000000..a940dbf52cc --- /dev/null +++ b/tests/baselines/reference/objectRestReadonly.js @@ -0,0 +1,36 @@ +//// [objectRestReadonly.ts] +// #23734 +type ObjType = { + foo: string + baz: string + quux: string +} + +const obj: Readonly = { + foo: 'bar', + baz: 'qux', + quux: 'quuz', +} + +const { foo, ...rest } = obj + +delete rest.baz + + +//// [objectRestReadonly.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var obj = { + foo: 'bar', + baz: 'qux', + quux: 'quuz' +}; +var foo = obj.foo, rest = __rest(obj, ["foo"]); +delete rest.baz; diff --git a/tests/baselines/reference/objectRestReadonly.symbols b/tests/baselines/reference/objectRestReadonly.symbols new file mode 100644 index 00000000000..91c95f915e1 --- /dev/null +++ b/tests/baselines/reference/objectRestReadonly.symbols @@ -0,0 +1,40 @@ +=== tests/cases/conformance/types/rest/objectRestReadonly.ts === +// #23734 +type ObjType = { +>ObjType : Symbol(ObjType, Decl(objectRestReadonly.ts, 0, 0)) + + foo: string +>foo : Symbol(foo, Decl(objectRestReadonly.ts, 1, 16)) + + baz: string +>baz : Symbol(baz, Decl(objectRestReadonly.ts, 2, 13)) + + quux: string +>quux : Symbol(quux, Decl(objectRestReadonly.ts, 3, 13)) +} + +const obj: Readonly = { +>obj : Symbol(obj, Decl(objectRestReadonly.ts, 7, 5)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>ObjType : Symbol(ObjType, Decl(objectRestReadonly.ts, 0, 0)) + + foo: 'bar', +>foo : Symbol(foo, Decl(objectRestReadonly.ts, 7, 32)) + + baz: 'qux', +>baz : Symbol(baz, Decl(objectRestReadonly.ts, 8, 13)) + + quux: 'quuz', +>quux : Symbol(quux, Decl(objectRestReadonly.ts, 9, 13)) +} + +const { foo, ...rest } = obj +>foo : Symbol(foo, Decl(objectRestReadonly.ts, 13, 7)) +>rest : Symbol(rest, Decl(objectRestReadonly.ts, 13, 12)) +>obj : Symbol(obj, Decl(objectRestReadonly.ts, 7, 5)) + +delete rest.baz +>rest.baz : Symbol(baz, Decl(objectRestReadonly.ts, 2, 13)) +>rest : Symbol(rest, Decl(objectRestReadonly.ts, 13, 12)) +>baz : Symbol(baz, Decl(objectRestReadonly.ts, 2, 13)) + diff --git a/tests/baselines/reference/objectRestReadonly.types b/tests/baselines/reference/objectRestReadonly.types new file mode 100644 index 00000000000..30fd21e896b --- /dev/null +++ b/tests/baselines/reference/objectRestReadonly.types @@ -0,0 +1,45 @@ +=== tests/cases/conformance/types/rest/objectRestReadonly.ts === +// #23734 +type ObjType = { +>ObjType : ObjType + + foo: string +>foo : string + + baz: string +>baz : string + + quux: string +>quux : string +} + +const obj: Readonly = { +>obj : Readonly +>Readonly : Readonly +>ObjType : ObjType +>{ foo: 'bar', baz: 'qux', quux: 'quuz',} : { foo: string; baz: string; quux: string; } + + foo: 'bar', +>foo : string +>'bar' : "bar" + + baz: 'qux', +>baz : string +>'qux' : "qux" + + quux: 'quuz', +>quux : string +>'quuz' : "quuz" +} + +const { foo, ...rest } = obj +>foo : string +>rest : { baz: string; quux: string; } +>obj : Readonly + +delete rest.baz +>delete rest.baz : boolean +>rest.baz : string +>rest : { baz: string; quux: string; } +>baz : string + diff --git a/tests/cases/conformance/types/rest/objectRestReadonly.ts b/tests/cases/conformance/types/rest/objectRestReadonly.ts new file mode 100644 index 00000000000..be600620348 --- /dev/null +++ b/tests/cases/conformance/types/rest/objectRestReadonly.ts @@ -0,0 +1,16 @@ +// #23734 +type ObjType = { + foo: string + baz: string + quux: string +} + +const obj: Readonly = { + foo: 'bar', + baz: 'qux', + quux: 'quuz', +} + +const { foo, ...rest } = obj + +delete rest.baz From 5756c3445747715f947fd2ea2e7cb5560c94e9e9 Mon Sep 17 00:00:00 2001 From: csigs Date: Fri, 27 Apr 2018 22:11:01 +0000 Subject: [PATCH 212/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 27 +++++++++++++++++++ .../diagnosticMessages.generated.json.lcl | 21 +++++++++++++++ .../diagnosticMessages.generated.json.lcl | 21 +++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 619c6ea41af..fa924a9d856 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1251,6 +1251,15 @@ + + + + + + + + + @@ -6504,6 +6513,15 @@ + + + + + + + + + @@ -8754,6 +8772,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index f8a6325f4a1..f7c9f90e59e 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1241,6 +1241,15 @@ + + + + + + + + + @@ -6494,6 +6503,9 @@ + + + @@ -8747,6 +8759,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3be5ddb0dbb..098f08d8cd2 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1250,6 +1250,15 @@ + + + + + + + + + @@ -6506,6 +6515,9 @@ + + + @@ -8759,6 +8771,15 @@ + + + + + + + + + From 6d3b6e21dad3a9f305be82e6a90b280963d5e80c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 27 Apr 2018 15:55:32 -0700 Subject: [PATCH 213/229] Add implicit any errors for destructuring computed names which aren't late bound and have no corresponding index (#23489) * Add implicit any errors for destructuring computed names which arent late bound and have no corresponding index * Add string fallback for number * Expand test case, make functionality mimic other (buggy) areas * Add symbol name errors to bring in line with new indexing rules --- src/compiler/checker.ts | 27 ++++- ...ndDestructuringImplicitAnyError.errors.txt | 49 ++++++++ .../lateBoundDestructuringImplicitAnyError.js | 55 +++++++++ ...BoundDestructuringImplicitAnyError.symbols | 95 +++++++++++++++ ...teBoundDestructuringImplicitAnyError.types | 114 ++++++++++++++++++ .../lateBoundDestructuringImplicitAnyError.ts | 30 +++++ 6 files changed, 368 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/lateBoundDestructuringImplicitAnyError.errors.txt create mode 100644 tests/baselines/reference/lateBoundDestructuringImplicitAnyError.js create mode 100644 tests/baselines/reference/lateBoundDestructuringImplicitAnyError.symbols create mode 100644 tests/baselines/reference/lateBoundDestructuringImplicitAnyError.types create mode 100644 tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3f1193947a1..7d94d64aae7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4227,12 +4227,29 @@ namespace ts { const isLate = isLateBindableName(name); const isWellKnown = isComputedPropertyName(name) && isWellKnownSymbolSyntactically(name.expression); if (!isLate && !isWellKnown && isComputedNonLiteralName(name)) { - return anyType; + const exprType = checkExpression((name as ComputedPropertyName).expression); + if (isTypeAssignableToKind(exprType, TypeFlags.ESSymbolLike)) { + if (noImplicitAny) { + error(declaration, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(exprType), typeToString(parentType)); + } + return anyType; + } + const indexerType = isTypeAssignableToKind(exprType, TypeFlags.NumberLike) && getIndexTypeOfType(parentType, IndexKind.Number) || getIndexTypeOfType(parentType, IndexKind.String); + if (!indexerType && noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) { + if (getIndexTypeOfType(parentType, IndexKind.Number)) { + error(declaration, Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number); + } + else { + error(declaration, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(parentType)); + } + } + return indexerType || anyType; } // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature, // or otherwise the type of the string index signature. - const text = isLate ? getLateBoundNameFromType(checkComputedPropertyName(name as ComputedPropertyName) as LiteralType | UniqueESSymbolType) : + const nameType = isLate && checkComputedPropertyName(name as ComputedPropertyName) as LiteralType | UniqueESSymbolType; + const text = isLate ? getLateBoundNameFromType(nameType) : isWellKnown ? getPropertyNameForKnownSymbolName(idText(((name as ComputedPropertyName).expression as PropertyAccessExpression).name)) : getTextOfPropertyName(name); @@ -4240,6 +4257,12 @@ namespace ts { if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) { parentType = getNonNullableType(parentType); } + if (isLate && nameType && !getPropertyOfType(parentType, text) && isTypeAssignableToKind(nameType, TypeFlags.ESSymbolLike)) { + if (noImplicitAny) { + error(declaration, Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(nameType), typeToString(parentType)); + } + return anyType; + } const declaredType = getConstraintForLocation(getTypeOfPropertyOfType(parentType, text), declaration.name); type = declaredType && getFlowTypeOfReference(declaration, declaredType) || isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) || diff --git a/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.errors.txt b/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.errors.txt new file mode 100644 index 00000000000..2e926ac1b83 --- /dev/null +++ b/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.errors.txt @@ -0,0 +1,49 @@ +tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(2,15): error TS7017: Element implicitly has an 'any' type because type '{ prop: string; }' has no index signature. +tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(13,15): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'. +tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(21,15): error TS2536: Type 'unique symbol' cannot be used to index type '{ [idx: number]: string; }'. +tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(23,15): error TS2536: Type 'unique symbol' cannot be used to index type '{ [idx: string]: string; }'. +tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(25,16): error TS2536: Type 'symbol' cannot be used to index type '{ [idx: number]: string; }'. +tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts(27,16): error TS2536: Type 'symbol' cannot be used to index type '{ [idx: string]: string; }'. + + +==== tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts (6 errors) ==== + let named = "foo"; + let {[named]: prop} = {prop: "foo"}; + ~~~~ +!!! error TS7017: Element implicitly has an 'any' type because type '{ prop: string; }' has no index signature. + void prop; + + const numIndexed: {[idx: number]: string} = null as any; + const strIndexed: {[idx: string]: string} = null as any; + + let numed = 6; + + const symed = Symbol(); + let symed2 = Symbol(); + + let {[named]: prop2} = numIndexed; + ~~~~~ +!!! error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'. + void prop2; + let {[numed]: prop3} = numIndexed; + void prop3; + let {[named]: prop4} = strIndexed; + void prop4; + let {[numed]: prop5} = strIndexed; + void prop5; + let {[symed]: prop6} = numIndexed; + ~~~~~ +!!! error TS2536: Type 'unique symbol' cannot be used to index type '{ [idx: number]: string; }'. + void prop6; + let {[symed]: prop7} = strIndexed; + ~~~~~ +!!! error TS2536: Type 'unique symbol' cannot be used to index type '{ [idx: string]: string; }'. + void prop7; + let {[symed2]: prop8} = numIndexed; + ~~~~~ +!!! error TS2536: Type 'symbol' cannot be used to index type '{ [idx: number]: string; }'. + void prop8; + let {[symed2]: prop9} = strIndexed; + ~~~~~ +!!! error TS2536: Type 'symbol' cannot be used to index type '{ [idx: string]: string; }'. + void prop9; \ No newline at end of file diff --git a/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.js b/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.js new file mode 100644 index 00000000000..61331a13564 --- /dev/null +++ b/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.js @@ -0,0 +1,55 @@ +//// [lateBoundDestructuringImplicitAnyError.ts] +let named = "foo"; +let {[named]: prop} = {prop: "foo"}; +void prop; + +const numIndexed: {[idx: number]: string} = null as any; +const strIndexed: {[idx: string]: string} = null as any; + +let numed = 6; + +const symed = Symbol(); +let symed2 = Symbol(); + +let {[named]: prop2} = numIndexed; +void prop2; +let {[numed]: prop3} = numIndexed; +void prop3; +let {[named]: prop4} = strIndexed; +void prop4; +let {[numed]: prop5} = strIndexed; +void prop5; +let {[symed]: prop6} = numIndexed; +void prop6; +let {[symed]: prop7} = strIndexed; +void prop7; +let {[symed2]: prop8} = numIndexed; +void prop8; +let {[symed2]: prop9} = strIndexed; +void prop9; + +//// [lateBoundDestructuringImplicitAnyError.js] +var named = "foo"; +var _a = named, prop = { prop: "foo" }[_a]; +void prop; +var numIndexed = null; +var strIndexed = null; +var numed = 6; +var symed = Symbol(); +var symed2 = Symbol(); +var _b = named, prop2 = numIndexed[_b]; +void prop2; +var _c = numed, prop3 = numIndexed[_c]; +void prop3; +var _d = named, prop4 = strIndexed[_d]; +void prop4; +var _e = numed, prop5 = strIndexed[_e]; +void prop5; +var _f = symed, prop6 = numIndexed[_f]; +void prop6; +var _g = symed, prop7 = strIndexed[_g]; +void prop7; +var _h = symed2, prop8 = numIndexed[_h]; +void prop8; +var _j = symed2, prop9 = strIndexed[_j]; +void prop9; diff --git a/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.symbols b/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.symbols new file mode 100644 index 00000000000..28bdf34a2ab --- /dev/null +++ b/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.symbols @@ -0,0 +1,95 @@ +=== tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts === +let named = "foo"; +>named : Symbol(named, Decl(lateBoundDestructuringImplicitAnyError.ts, 0, 3)) + +let {[named]: prop} = {prop: "foo"}; +>named : Symbol(named, Decl(lateBoundDestructuringImplicitAnyError.ts, 0, 3)) +>prop : Symbol(prop, Decl(lateBoundDestructuringImplicitAnyError.ts, 1, 5)) +>prop : Symbol(prop, Decl(lateBoundDestructuringImplicitAnyError.ts, 1, 23)) + +void prop; +>prop : Symbol(prop, Decl(lateBoundDestructuringImplicitAnyError.ts, 1, 5)) + +const numIndexed: {[idx: number]: string} = null as any; +>numIndexed : Symbol(numIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 4, 5)) +>idx : Symbol(idx, Decl(lateBoundDestructuringImplicitAnyError.ts, 4, 20)) + +const strIndexed: {[idx: string]: string} = null as any; +>strIndexed : Symbol(strIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 5, 5)) +>idx : Symbol(idx, Decl(lateBoundDestructuringImplicitAnyError.ts, 5, 20)) + +let numed = 6; +>numed : Symbol(numed, Decl(lateBoundDestructuringImplicitAnyError.ts, 7, 3)) + +const symed = Symbol(); +>symed : Symbol(symed, Decl(lateBoundDestructuringImplicitAnyError.ts, 9, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) + +let symed2 = Symbol(); +>symed2 : Symbol(symed2, Decl(lateBoundDestructuringImplicitAnyError.ts, 10, 3)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) + +let {[named]: prop2} = numIndexed; +>named : Symbol(named, Decl(lateBoundDestructuringImplicitAnyError.ts, 0, 3)) +>prop2 : Symbol(prop2, Decl(lateBoundDestructuringImplicitAnyError.ts, 12, 5)) +>numIndexed : Symbol(numIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 4, 5)) + +void prop2; +>prop2 : Symbol(prop2, Decl(lateBoundDestructuringImplicitAnyError.ts, 12, 5)) + +let {[numed]: prop3} = numIndexed; +>numed : Symbol(numed, Decl(lateBoundDestructuringImplicitAnyError.ts, 7, 3)) +>prop3 : Symbol(prop3, Decl(lateBoundDestructuringImplicitAnyError.ts, 14, 5)) +>numIndexed : Symbol(numIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 4, 5)) + +void prop3; +>prop3 : Symbol(prop3, Decl(lateBoundDestructuringImplicitAnyError.ts, 14, 5)) + +let {[named]: prop4} = strIndexed; +>named : Symbol(named, Decl(lateBoundDestructuringImplicitAnyError.ts, 0, 3)) +>prop4 : Symbol(prop4, Decl(lateBoundDestructuringImplicitAnyError.ts, 16, 5)) +>strIndexed : Symbol(strIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 5, 5)) + +void prop4; +>prop4 : Symbol(prop4, Decl(lateBoundDestructuringImplicitAnyError.ts, 16, 5)) + +let {[numed]: prop5} = strIndexed; +>numed : Symbol(numed, Decl(lateBoundDestructuringImplicitAnyError.ts, 7, 3)) +>prop5 : Symbol(prop5, Decl(lateBoundDestructuringImplicitAnyError.ts, 18, 5)) +>strIndexed : Symbol(strIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 5, 5)) + +void prop5; +>prop5 : Symbol(prop5, Decl(lateBoundDestructuringImplicitAnyError.ts, 18, 5)) + +let {[symed]: prop6} = numIndexed; +>symed : Symbol(symed, Decl(lateBoundDestructuringImplicitAnyError.ts, 9, 5)) +>prop6 : Symbol(prop6, Decl(lateBoundDestructuringImplicitAnyError.ts, 20, 5)) +>numIndexed : Symbol(numIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 4, 5)) + +void prop6; +>prop6 : Symbol(prop6, Decl(lateBoundDestructuringImplicitAnyError.ts, 20, 5)) + +let {[symed]: prop7} = strIndexed; +>symed : Symbol(symed, Decl(lateBoundDestructuringImplicitAnyError.ts, 9, 5)) +>prop7 : Symbol(prop7, Decl(lateBoundDestructuringImplicitAnyError.ts, 22, 5)) +>strIndexed : Symbol(strIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 5, 5)) + +void prop7; +>prop7 : Symbol(prop7, Decl(lateBoundDestructuringImplicitAnyError.ts, 22, 5)) + +let {[symed2]: prop8} = numIndexed; +>symed2 : Symbol(symed2, Decl(lateBoundDestructuringImplicitAnyError.ts, 10, 3)) +>prop8 : Symbol(prop8, Decl(lateBoundDestructuringImplicitAnyError.ts, 24, 5)) +>numIndexed : Symbol(numIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 4, 5)) + +void prop8; +>prop8 : Symbol(prop8, Decl(lateBoundDestructuringImplicitAnyError.ts, 24, 5)) + +let {[symed2]: prop9} = strIndexed; +>symed2 : Symbol(symed2, Decl(lateBoundDestructuringImplicitAnyError.ts, 10, 3)) +>prop9 : Symbol(prop9, Decl(lateBoundDestructuringImplicitAnyError.ts, 26, 5)) +>strIndexed : Symbol(strIndexed, Decl(lateBoundDestructuringImplicitAnyError.ts, 5, 5)) + +void prop9; +>prop9 : Symbol(prop9, Decl(lateBoundDestructuringImplicitAnyError.ts, 26, 5)) + diff --git a/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.types b/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.types new file mode 100644 index 00000000000..92d2c4c662c --- /dev/null +++ b/tests/baselines/reference/lateBoundDestructuringImplicitAnyError.types @@ -0,0 +1,114 @@ +=== tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts === +let named = "foo"; +>named : string +>"foo" : "foo" + +let {[named]: prop} = {prop: "foo"}; +>named : string +>prop : any +>{prop: "foo"} : { prop: string; } +>prop : string +>"foo" : "foo" + +void prop; +>void prop : undefined +>prop : any + +const numIndexed: {[idx: number]: string} = null as any; +>numIndexed : { [idx: number]: string; } +>idx : number +>null as any : any +>null : null + +const strIndexed: {[idx: string]: string} = null as any; +>strIndexed : { [idx: string]: string; } +>idx : string +>null as any : any +>null : null + +let numed = 6; +>numed : number +>6 : 6 + +const symed = Symbol(); +>symed : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +let symed2 = Symbol(); +>symed2 : symbol +>Symbol() : symbol +>Symbol : SymbolConstructor + +let {[named]: prop2} = numIndexed; +>named : string +>prop2 : any +>numIndexed : { [idx: number]: string; } + +void prop2; +>void prop2 : undefined +>prop2 : any + +let {[numed]: prop3} = numIndexed; +>numed : number +>prop3 : string +>numIndexed : { [idx: number]: string; } + +void prop3; +>void prop3 : undefined +>prop3 : string + +let {[named]: prop4} = strIndexed; +>named : string +>prop4 : string +>strIndexed : { [idx: string]: string; } + +void prop4; +>void prop4 : undefined +>prop4 : string + +let {[numed]: prop5} = strIndexed; +>numed : number +>prop5 : string +>strIndexed : { [idx: string]: string; } + +void prop5; +>void prop5 : undefined +>prop5 : string + +let {[symed]: prop6} = numIndexed; +>symed : unique symbol +>prop6 : any +>numIndexed : { [idx: number]: string; } + +void prop6; +>void prop6 : undefined +>prop6 : any + +let {[symed]: prop7} = strIndexed; +>symed : unique symbol +>prop7 : any +>strIndexed : { [idx: string]: string; } + +void prop7; +>void prop7 : undefined +>prop7 : any + +let {[symed2]: prop8} = numIndexed; +>symed2 : symbol +>prop8 : any +>numIndexed : { [idx: number]: string; } + +void prop8; +>void prop8 : undefined +>prop8 : any + +let {[symed2]: prop9} = strIndexed; +>symed2 : symbol +>prop9 : any +>strIndexed : { [idx: string]: string; } + +void prop9; +>void prop9 : undefined +>prop9 : any + diff --git a/tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts b/tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts new file mode 100644 index 00000000000..800675c7823 --- /dev/null +++ b/tests/cases/compiler/lateBoundDestructuringImplicitAnyError.ts @@ -0,0 +1,30 @@ +// @lib: es6 +// @noImplicitAny: true +let named = "foo"; +let {[named]: prop} = {prop: "foo"}; +void prop; + +const numIndexed: {[idx: number]: string} = null as any; +const strIndexed: {[idx: string]: string} = null as any; + +let numed = 6; + +const symed = Symbol(); +let symed2 = Symbol(); + +let {[named]: prop2} = numIndexed; +void prop2; +let {[numed]: prop3} = numIndexed; +void prop3; +let {[named]: prop4} = strIndexed; +void prop4; +let {[numed]: prop5} = strIndexed; +void prop5; +let {[symed]: prop6} = numIndexed; +void prop6; +let {[symed]: prop7} = strIndexed; +void prop7; +let {[symed2]: prop8} = numIndexed; +void prop8; +let {[symed2]: prop9} = strIndexed; +void prop9; \ No newline at end of file From 47385b29e0ea1b14b2db85b6b34540d591adfa0f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 27 Apr 2018 15:55:53 -0700 Subject: [PATCH 214/229] Actually visit expression node on empty destructuring assignment (#23744) --- src/compiler/transformers/destructuring.ts | 2 +- ...ructuringExpressionVisitedByTransformer.js | 7 ++++++ ...ringExpressionVisitedByTransformer.symbols | 15 +++++++++++ ...turingExpressionVisitedByTransformer.types | 25 +++++++++++++++++++ ...ructuringExpressionVisitedByTransformer.ts | 2 ++ 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.js create mode 100644 tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.symbols create mode 100644 tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.types create mode 100644 tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 35101d3be7f..2dd8946e8e2 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -46,7 +46,7 @@ namespace ts { value = node.right; } else { - return value; + return visitNode(value, visitor, isExpression); } } } diff --git a/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.js b/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.js new file mode 100644 index 00000000000..5e7e333f7a6 --- /dev/null +++ b/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.js @@ -0,0 +1,7 @@ +//// [emptyArrayDestructuringExpressionVisitedByTransformer.ts] +var a = [] = [1].map(_ => _); +var b = [1].map(_ => _); + +//// [emptyArrayDestructuringExpressionVisitedByTransformer.js] +var a = [1].map(function (_) { return _; }); +var b = [1].map(function (_) { return _; }); diff --git a/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.symbols b/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.symbols new file mode 100644 index 00000000000..5694d47c8c8 --- /dev/null +++ b/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts === +var a = [] = [1].map(_ => _); +>a : Symbol(a, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 0, 3)) +>[1].map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>_ : Symbol(_, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 0, 21)) +>_ : Symbol(_, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 0, 21)) + +var b = [1].map(_ => _); +>b : Symbol(b, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 1, 3)) +>[1].map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>_ : Symbol(_, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 1, 16)) +>_ : Symbol(_, Decl(emptyArrayDestructuringExpressionVisitedByTransformer.ts, 1, 16)) + diff --git a/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.types b/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.types new file mode 100644 index 00000000000..450a24a0fa7 --- /dev/null +++ b/tests/baselines/reference/emptyArrayDestructuringExpressionVisitedByTransformer.types @@ -0,0 +1,25 @@ +=== tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts === +var a = [] = [1].map(_ => _); +>a : number[] +>[] = [1].map(_ => _) : number[] +>[] : undefined[] +>[1].map(_ => _) : number[] +>[1].map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] +>[1] : number[] +>1 : 1 +>map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] +>_ => _ : (_: number) => number +>_ : number +>_ : number + +var b = [1].map(_ => _); +>b : number[] +>[1].map(_ => _) : number[] +>[1].map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] +>[1] : number[] +>1 : 1 +>map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] +>_ => _ : (_: number) => number +>_ : number +>_ : number + diff --git a/tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts b/tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts new file mode 100644 index 00000000000..01ad2d61122 --- /dev/null +++ b/tests/cases/compiler/emptyArrayDestructuringExpressionVisitedByTransformer.ts @@ -0,0 +1,2 @@ +var a = [] = [1].map(_ => _); +var b = [1].map(_ => _); \ No newline at end of file From 8c5ad2429a8a437e5d075c7d8ddde85ab01f0a7e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 27 Apr 2018 16:30:43 -0700 Subject: [PATCH 215/229] Relax switch-case narrowing restrictions (#23522) * Allow switch case narrowing even when individual clauses are nonunit * And remove unit type restriction * Rename --- src/compiler/checker.ts | 17 ++-- tests/baselines/reference/literalTypes1.types | 6 +- ...stringLiteralsWithSwitchStatements03.types | 2 +- ...gClausesEvenWhenNonMatchingClausesExist.js | 83 +++++++++++++++++++ ...sesEvenWhenNonMatchingClausesExist.symbols | 67 +++++++++++++++ ...ausesEvenWhenNonMatchingClausesExist.types | 79 ++++++++++++++++++ ...gClausesEvenWhenNonMatchingClausesExist.ts | 40 +++++++++ 7 files changed, 280 insertions(+), 14 deletions(-) create mode 100644 tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.js create mode 100644 tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.symbols create mode 100644 tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.types create mode 100644 tests/cases/compiler/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7d94d64aae7..ccdbadf4252 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11570,6 +11570,10 @@ namespace ts { return !!getPropertyOfType(type, "0" as __String); } + function isNeitherUnitTypeNorNever(type: Type): boolean { + return !(type.flags & (TypeFlags.Unit | TypeFlags.Never)); + } + function isUnitType(type: Type): boolean { return !!(type.flags & TypeFlags.Unit); } @@ -13049,8 +13053,7 @@ namespace ts { function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) { if (clause.kind === SyntaxKind.CaseClause) { - const caseType = getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression)); - return isUnitType(caseType) ? caseType : undefined; + return getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression)); } return neverType; } @@ -13058,15 +13061,9 @@ namespace ts { function getSwitchClauseTypes(switchStatement: SwitchStatement): Type[] { const links = getNodeLinks(switchStatement); if (!links.switchTypes) { - // If all case clauses specify expressions that have unit types, we return an array - // of those unit types. Otherwise we return an empty array. links.switchTypes = []; for (const clause of switchStatement.caseBlock.clauses) { - const type = getTypeOfSwitchClause(clause); - if (type === undefined) { - return links.switchTypes = emptyArray; - } - links.switchTypes.push(type); + links.switchTypes.push(getTypeOfSwitchClause(clause)); } } return links.switchTypes; @@ -19170,7 +19167,7 @@ namespace ts { return false; } const switchTypes = getSwitchClauseTypes(node); - if (!switchTypes.length) { + if (!switchTypes.length || some(switchTypes, isNeitherUnitTypeNorNever)) { return false; } return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes); diff --git a/tests/baselines/reference/literalTypes1.types b/tests/baselines/reference/literalTypes1.types index ed2df4ca14c..cb612cab4dd 100644 --- a/tests/baselines/reference/literalTypes1.types +++ b/tests/baselines/reference/literalTypes1.types @@ -61,19 +61,19 @@ function f2(x: 0 | 1 | 2) { >zero : 0 x; ->x : 0 | 1 | 2 +>x : 0 break; case oneOrTwo: >oneOrTwo : 1 | 2 x; ->x : 0 | 1 | 2 +>x : 1 | 2 break; default: x; ->x : 0 | 1 | 2 +>x : 1 | 2 } } diff --git a/tests/baselines/reference/stringLiteralsWithSwitchStatements03.types b/tests/baselines/reference/stringLiteralsWithSwitchStatements03.types index 2b4b3e0fae9..70f6d6cc973 100644 --- a/tests/baselines/reference/stringLiteralsWithSwitchStatements03.types +++ b/tests/baselines/reference/stringLiteralsWithSwitchStatements03.types @@ -51,7 +51,7 @@ switch (x) { >"baz" : "baz" x; ->x : "foo" +>x : never y; >y : "foo" | "bar" diff --git a/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.js b/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.js new file mode 100644 index 00000000000..800209fde7a --- /dev/null +++ b/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.js @@ -0,0 +1,83 @@ +//// [switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts] +export const narrowToLiterals = (str: string) => { + switch (str) { + case 'abc': { + // inferred type as `abc` + return str; + } + default: + return 'defaultValue'; + } + }; + + export const narrowToString = (str: string, someOtherStr: string) => { + switch (str) { + case 'abc': { + // inferred type should be `abc` + return str; + } + case someOtherStr: { + // `string` + return str; + } + default: + return 'defaultValue'; + } + }; + + export const narrowToStringOrNumber = (str: string | number, someNumber: number) => { + switch (str) { + case 'abc': { + // inferred type should be `abc` + return str; + } + case someNumber: { + // inferred type should be `number` + return str; + } + default: + return 'defaultValue'; + } + }; + +//// [switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.js] +"use strict"; +exports.__esModule = true; +exports.narrowToLiterals = function (str) { + switch (str) { + case 'abc': { + // inferred type as `abc` + return str; + } + default: + return 'defaultValue'; + } +}; +exports.narrowToString = function (str, someOtherStr) { + switch (str) { + case 'abc': { + // inferred type should be `abc` + return str; + } + case someOtherStr: { + // `string` + return str; + } + default: + return 'defaultValue'; + } +}; +exports.narrowToStringOrNumber = function (str, someNumber) { + switch (str) { + case 'abc': { + // inferred type should be `abc` + return str; + } + case someNumber: { + // inferred type should be `number` + return str; + } + default: + return 'defaultValue'; + } +}; diff --git a/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.symbols b/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.symbols new file mode 100644 index 00000000000..64b8ad44c97 --- /dev/null +++ b/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.symbols @@ -0,0 +1,67 @@ +=== tests/cases/compiler/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts === +export const narrowToLiterals = (str: string) => { +>narrowToLiterals : Symbol(narrowToLiterals, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 0, 12)) +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 0, 33)) + + switch (str) { +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 0, 33)) + + case 'abc': { + // inferred type as `abc` + return str; +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 0, 33)) + } + default: + return 'defaultValue'; + } + }; + + export const narrowToString = (str: string, someOtherStr: string) => { +>narrowToString : Symbol(narrowToString, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 11, 14)) +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 11, 33)) +>someOtherStr : Symbol(someOtherStr, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 11, 45)) + + switch (str) { +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 11, 33)) + + case 'abc': { + // inferred type should be `abc` + return str; +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 11, 33)) + } + case someOtherStr: { +>someOtherStr : Symbol(someOtherStr, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 11, 45)) + + // `string` + return str; +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 11, 33)) + } + default: + return 'defaultValue'; + } + }; + + export const narrowToStringOrNumber = (str: string | number, someNumber: number) => { +>narrowToStringOrNumber : Symbol(narrowToStringOrNumber, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 26, 14)) +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 26, 41)) +>someNumber : Symbol(someNumber, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 26, 62)) + + switch (str) { +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 26, 41)) + + case 'abc': { + // inferred type should be `abc` + return str; +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 26, 41)) + } + case someNumber: { +>someNumber : Symbol(someNumber, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 26, 62)) + + // inferred type should be `number` + return str; +>str : Symbol(str, Decl(switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts, 26, 41)) + } + default: + return 'defaultValue'; + } + }; diff --git a/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.types b/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.types new file mode 100644 index 00000000000..f8c14745075 --- /dev/null +++ b/tests/baselines/reference/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.types @@ -0,0 +1,79 @@ +=== tests/cases/compiler/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts === +export const narrowToLiterals = (str: string) => { +>narrowToLiterals : (str: string) => "abc" | "defaultValue" +>(str: string) => { switch (str) { case 'abc': { // inferred type as `abc` return str; } default: return 'defaultValue'; } } : (str: string) => "abc" | "defaultValue" +>str : string + + switch (str) { +>str : string + + case 'abc': { +>'abc' : "abc" + + // inferred type as `abc` + return str; +>str : "abc" + } + default: + return 'defaultValue'; +>'defaultValue' : "defaultValue" + } + }; + + export const narrowToString = (str: string, someOtherStr: string) => { +>narrowToString : (str: string, someOtherStr: string) => string +>(str: string, someOtherStr: string) => { switch (str) { case 'abc': { // inferred type should be `abc` return str; } case someOtherStr: { // `string` return str; } default: return 'defaultValue'; } } : (str: string, someOtherStr: string) => string +>str : string +>someOtherStr : string + + switch (str) { +>str : string + + case 'abc': { +>'abc' : "abc" + + // inferred type should be `abc` + return str; +>str : "abc" + } + case someOtherStr: { +>someOtherStr : string + + // `string` + return str; +>str : string + } + default: + return 'defaultValue'; +>'defaultValue' : "defaultValue" + } + }; + + export const narrowToStringOrNumber = (str: string | number, someNumber: number) => { +>narrowToStringOrNumber : (str: string | number, someNumber: number) => number | "abc" | "defaultValue" +>(str: string | number, someNumber: number) => { switch (str) { case 'abc': { // inferred type should be `abc` return str; } case someNumber: { // inferred type should be `number` return str; } default: return 'defaultValue'; } } : (str: string | number, someNumber: number) => number | "abc" | "defaultValue" +>str : string | number +>someNumber : number + + switch (str) { +>str : string | number + + case 'abc': { +>'abc' : "abc" + + // inferred type should be `abc` + return str; +>str : "abc" + } + case someNumber: { +>someNumber : number + + // inferred type should be `number` + return str; +>str : number + } + default: + return 'defaultValue'; +>'defaultValue' : "defaultValue" + } + }; diff --git a/tests/cases/compiler/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts b/tests/cases/compiler/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts new file mode 100644 index 00000000000..2d3ebdd1e2a --- /dev/null +++ b/tests/cases/compiler/switchCaseNarrowsMatchingClausesEvenWhenNonMatchingClausesExist.ts @@ -0,0 +1,40 @@ +export const narrowToLiterals = (str: string) => { + switch (str) { + case 'abc': { + // inferred type as `abc` + return str; + } + default: + return 'defaultValue'; + } + }; + + export const narrowToString = (str: string, someOtherStr: string) => { + switch (str) { + case 'abc': { + // inferred type should be `abc` + return str; + } + case someOtherStr: { + // `string` + return str; + } + default: + return 'defaultValue'; + } + }; + + export const narrowToStringOrNumber = (str: string | number, someNumber: number) => { + switch (str) { + case 'abc': { + // inferred type should be `abc` + return str; + } + case someNumber: { + // inferred type should be `number` + return str; + } + default: + return 'defaultValue'; + } + }; \ No newline at end of file From 38d1f7f0d22e5d706af3e18146fb2fcb4333b4c6 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 27 Apr 2018 16:50:09 -0700 Subject: [PATCH 216/229] Add tests --- .../types/intersection/intersectionReduction.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/cases/conformance/types/intersection/intersectionReduction.ts diff --git a/tests/cases/conformance/types/intersection/intersectionReduction.ts b/tests/cases/conformance/types/intersection/intersectionReduction.ts new file mode 100644 index 00000000000..b3b8950c330 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionReduction.ts @@ -0,0 +1,15 @@ +// @strict + +declare const sym1: unique symbol; +declare const sym2: unique symbol; + +type T1 = string & 'a'; // 'a' +type T2 = 'a' & string & 'b'; // 'a' & 'b' +type T3 = number & 10; // 10 +type T4 = 10 & number & 20; // 10 & 20 +type T5 = symbol & typeof sym1; // typeof sym1 +type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 + +type T10 = string & ('a' | 'b'); // 'a' | 'b' +type T11 = (string | number) & ('a' | 10); // 'a' | 10 From e80b47da9e601f3d0ebd7173c3905f07a49e8e8c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 27 Apr 2018 16:50:17 -0700 Subject: [PATCH 217/229] Accept new baselines --- .../reference/intersectionReduction.js | 20 ++++++++++ .../reference/intersectionReduction.symbols | 40 +++++++++++++++++++ .../reference/intersectionReduction.types | 40 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 tests/baselines/reference/intersectionReduction.js create mode 100644 tests/baselines/reference/intersectionReduction.symbols create mode 100644 tests/baselines/reference/intersectionReduction.types diff --git a/tests/baselines/reference/intersectionReduction.js b/tests/baselines/reference/intersectionReduction.js new file mode 100644 index 00000000000..1b985a79b9f --- /dev/null +++ b/tests/baselines/reference/intersectionReduction.js @@ -0,0 +1,20 @@ +//// [intersectionReduction.ts] +// @strict + +declare const sym1: unique symbol; +declare const sym2: unique symbol; + +type T1 = string & 'a'; // 'a' +type T2 = 'a' & string & 'b'; // 'a' & 'b' +type T3 = number & 10; // 10 +type T4 = 10 & number & 20; // 10 & 20 +type T5 = symbol & typeof sym1; // typeof sym1 +type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 + +type T10 = string & ('a' | 'b'); // 'a' | 'b' +type T11 = (string | number) & ('a' | 10); // 'a' | 10 + + +//// [intersectionReduction.js] +// @strict diff --git a/tests/baselines/reference/intersectionReduction.symbols b/tests/baselines/reference/intersectionReduction.symbols new file mode 100644 index 00000000000..607ea1d6c48 --- /dev/null +++ b/tests/baselines/reference/intersectionReduction.symbols @@ -0,0 +1,40 @@ +=== tests/cases/conformance/types/intersection/intersectionReduction.ts === +// @strict + +declare const sym1: unique symbol; +>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) + +declare const sym2: unique symbol; +>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13)) + +type T1 = string & 'a'; // 'a' +>T1 : Symbol(T1, Decl(intersectionReduction.ts, 3, 34)) + +type T2 = 'a' & string & 'b'; // 'a' & 'b' +>T2 : Symbol(T2, Decl(intersectionReduction.ts, 5, 23)) + +type T3 = number & 10; // 10 +>T3 : Symbol(T3, Decl(intersectionReduction.ts, 6, 29)) + +type T4 = 10 & number & 20; // 10 & 20 +>T4 : Symbol(T4, Decl(intersectionReduction.ts, 7, 22)) + +type T5 = symbol & typeof sym1; // typeof sym1 +>T5 : Symbol(T5, Decl(intersectionReduction.ts, 8, 27)) +>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) + +type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 +>T6 : Symbol(T6, Decl(intersectionReduction.ts, 9, 31)) +>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) +>sym2 : Symbol(sym2, Decl(intersectionReduction.ts, 3, 13)) + +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 +>T7 : Symbol(T7, Decl(intersectionReduction.ts, 10, 45)) +>sym1 : Symbol(sym1, Decl(intersectionReduction.ts, 2, 13)) + +type T10 = string & ('a' | 'b'); // 'a' | 'b' +>T10 : Symbol(T10, Decl(intersectionReduction.ts, 11, 60)) + +type T11 = (string | number) & ('a' | 10); // 'a' | 10 +>T11 : Symbol(T11, Decl(intersectionReduction.ts, 13, 32)) + diff --git a/tests/baselines/reference/intersectionReduction.types b/tests/baselines/reference/intersectionReduction.types new file mode 100644 index 00000000000..f8c178cfca4 --- /dev/null +++ b/tests/baselines/reference/intersectionReduction.types @@ -0,0 +1,40 @@ +=== tests/cases/conformance/types/intersection/intersectionReduction.ts === +// @strict + +declare const sym1: unique symbol; +>sym1 : unique symbol + +declare const sym2: unique symbol; +>sym2 : unique symbol + +type T1 = string & 'a'; // 'a' +>T1 : "a" + +type T2 = 'a' & string & 'b'; // 'a' & 'b' +>T2 : T2 + +type T3 = number & 10; // 10 +>T3 : 10 + +type T4 = 10 & number & 20; // 10 & 20 +>T4 : T4 + +type T5 = symbol & typeof sym1; // typeof sym1 +>T5 : unique symbol +>sym1 : unique symbol + +type T6 = typeof sym1 & symbol & typeof sym2; // typeof sym1 & typeof sym2 +>T6 : T6 +>sym1 : unique symbol +>sym2 : unique symbol + +type T7 = string & 'a' & number & 10 & symbol & typeof sym1; // 'a' & 10 & typeof sym1 +>T7 : T7 +>sym1 : unique symbol + +type T10 = string & ('a' | 'b'); // 'a' | 'b' +>T10 : "a" | "b" + +type T11 = (string | number) & ('a' | 10); // 'a' | 10 +>T11 : "a" | 10 + From 44066d6c7afa7ffd9cca1d17d84b3730d65ebfbb Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 27 Apr 2018 16:42:36 -0700 Subject: [PATCH 218/229] Handle the test case when tsconfig file changes without needing to update the program Fixes #23687 --- src/compiler/builder.ts | 2 +- src/compiler/tsc.ts | 9 +++-- src/compiler/watch.ts | 18 ++++++---- src/harness/unittests/tscWatchMode.ts | 22 +++++++++++++ src/harness/virtualFileSystemWithWatch.ts | 40 ++++++++++++++--------- 5 files changed, 65 insertions(+), 26 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 92e651061ed..6dd3226e550 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -249,7 +249,7 @@ namespace ts { export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, host, oldProgram, configFileParsingDiagnostics }: BuilderCreationParameters) { // Return same program if underlying program doesnt change let oldState = oldProgram && oldProgram.getState(); - if (oldState && newProgram === oldState.program && configFileParsingDiagnostics !== newProgram.getConfigFileParsingDiagnostics()) { + if (oldState && newProgram === oldState.program && configFileParsingDiagnostics === newProgram.getConfigFileParsingDiagnostics()) { newProgram = undefined; oldState = undefined; return oldProgram; diff --git a/src/compiler/tsc.ts b/src/compiler/tsc.ts index 3c73eba86ef..e45a95f7989 100644 --- a/src/compiler/tsc.ts +++ b/src/compiler/tsc.ts @@ -154,9 +154,12 @@ namespace ts { function updateWatchCompilationHost(watchCompilerHost: WatchCompilerHost) { const compileUsingBuilder = watchCompilerHost.createProgram; - watchCompilerHost.createProgram = (rootNames, options, host, oldProgram) => { - enableStatistics(options); - return compileUsingBuilder(rootNames, options, host, oldProgram); + watchCompilerHost.createProgram = (rootNames, options, host, oldProgram, configFileParsingDiagnostics) => { + Debug.assert(rootNames !== undefined || (options === undefined && !!oldProgram)); + if (options !== undefined) { + enableStatistics(options); + } + return compileUsingBuilder(rootNames, options, host, oldProgram, configFileParsingDiagnostics); }; const emitFilesUsingBuilder = watchCompilerHost.afterProgramCreate; watchCompilerHost.afterProgramCreate = builderProgram => { diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index f0bb151b814..9ec362a12c0 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -625,9 +625,19 @@ namespace ts { builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics); hasChangedConfigFileParsingErrors = false; } - return builderProgram; + } + else { + createNewProgram(program, hasInvalidatedResolution); } + if (host.afterProgramCreate) { + host.afterProgramCreate(builderProgram); + } + + return builderProgram; + } + + function createNewProgram(program: Program, hasInvalidatedResolution: HasInvalidatedResolution) { // Compile the program if (watchLogLevel !== WatchLogLevel.None) { writeLog("CreatingProgramWith::"); @@ -663,12 +673,6 @@ namespace ts { } missingFilePathsRequestedForRelease = undefined; } - - if (host.afterProgramCreate) { - host.afterProgramCreate(builderProgram); - } - - return builderProgram; } function updateRootFileNames(files: string[]) { diff --git a/src/harness/unittests/tscWatchMode.ts b/src/harness/unittests/tscWatchMode.ts index 44565c0ddbe..ca681a8f8ce 100644 --- a/src/harness/unittests/tscWatchMode.ts +++ b/src/harness/unittests/tscWatchMode.ts @@ -418,6 +418,28 @@ namespace ts.tscWatch { checkProgramRootFiles(watch(), [commonFile1.path]); }); + it("works correctly when config file is changed but its content havent", () => { + const configFile: FileOrFolder = { + path: "/a/b/tsconfig.json", + content: `{ + "compilerOptions": {}, + "files": ["${commonFile1.path}", "${commonFile2.path}"] + }` + }; + const files = [libFile, commonFile1, commonFile2, configFile]; + const host = createWatchedSystem(files); + const watch = createWatchOfConfigFile(configFile.path, host); + + checkProgramActualFiles(watch(), [libFile.path, commonFile1.path, commonFile2.path]); + checkOutputErrorsInitial(host, emptyArray); + + host.modifyFile(configFile.path, configFile.content); + host.checkTimeoutQueueLengthAndRun(1); // reload the configured project + + checkProgramActualFiles(watch(), [libFile.path, commonFile1.path, commonFile2.path]); + checkOutputErrorsIncremental(host, emptyArray); + }); + it("files explicitly excluded in config file", () => { const configFile: FileOrFolder = { path: "/a/b/tsconfig.json", diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 3756f435d43..323a51c25ae 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -393,21 +393,7 @@ interface Array {}` if (isString(fileOrDirectory.content)) { // Update file if (currentEntry.content !== fileOrDirectory.content) { - if (options && options.invokeFileDeleteCreateAsPartInsteadOfChange) { - this.removeFileOrFolder(currentEntry, returnFalse); - this.ensureFileOrFolder(fileOrDirectory); - } - else { - currentEntry.content = fileOrDirectory.content; - currentEntry.modifiedTime = this.now(); - this.fs.get(getDirectoryPath(currentEntry.path)).modifiedTime = this.now(); - if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) { - this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath); - } - else { - this.invokeFileWatcher(currentEntry.fullPath, FileWatcherEventKind.Changed); - } - } + this.modifyFile(fileOrDirectory.path, fileOrDirectory.content, options); } } else { @@ -446,6 +432,30 @@ interface Array {}` } } + modifyFile(filePath: string, content: string, options?: Partial) { + const path = this.toFullPath(filePath); + const currentEntry = this.fs.get(path); + if (!currentEntry || !isFile(currentEntry)) { + throw new Error(`file not present: ${filePath}`); + } + + if (options && options.invokeFileDeleteCreateAsPartInsteadOfChange) { + this.removeFileOrFolder(currentEntry, returnFalse); + this.ensureFileOrFolder({ path: filePath, content }); + } + else { + currentEntry.content = content; + currentEntry.modifiedTime = this.now(); + this.fs.get(getDirectoryPath(currentEntry.path)).modifiedTime = this.now(); + if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) { + this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath); + } + else { + this.invokeFileWatcher(currentEntry.fullPath, FileWatcherEventKind.Changed); + } + } + } + renameFolder(folderName: string, newFolderName: string) { const fullPath = getNormalizedAbsolutePath(folderName, this.currentDirectory); const path = this.toPath(fullPath); From bc0d3e129700b6dda0fb504c5c55bf95f7a4f7d7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 27 Apr 2018 17:19:57 -0700 Subject: [PATCH 219/229] Look for top-level imports/exports before diving into the tree. --- src/compiler/parser.ts | 24 +++++++++++++++--------- src/compiler/types.ts | 6 +++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 12e498787c8..32e7ca19dd3 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -6139,14 +6139,11 @@ namespace ts { } function setExternalModuleIndicator(sourceFile: SourceFile) { - // Usually we'd like to avoid a full tree walk, but it's possible - // that we have a deeper external module indicator (e.g. `import.meta`, - // and possibly nested import statements in the future). - // Ideally the first few statements will be an import/export anyway. + // Try to use the first top-level import/export when available, then + // fall back to looking for an 'import.meta' somewhere in the tree if necessary. sourceFile.externalModuleIndicator = - !(sourceFile.flags & NodeFlags.PossiblyContainsImportMeta) ? - forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) : - walkTreeForExternalModuleIndicators(sourceFile); + forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) || + getImportMetaIfNecessary(sourceFile); } function isAnExternalModuleIndicatorNode(node: Node) { @@ -6155,13 +6152,22 @@ namespace ts { || node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ExportAssignment || node.kind === SyntaxKind.ExportDeclaration - || isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta" ? node : undefined; } + function getImportMetaIfNecessary(sourceFile: SourceFile) { + return sourceFile.flags & NodeFlags.PossiblyContainsImportMeta ? + walkTreeForExternalModuleIndicators(sourceFile) : + undefined; + } + function walkTreeForExternalModuleIndicators(node: Node): Node { - return isAnExternalModuleIndicatorNode(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators); + return isImportMeta(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators); + } + + function isImportMeta(node: Node): boolean { + return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta"; } const enum ParsingContext { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c678c4dab93..2622fe3f5e4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2564,7 +2564,11 @@ namespace ts { languageVersion: ScriptTarget; /* @internal */ scriptKind: ScriptKind; - // The first node that causes this file to be an external module + /** + * The first "most obvious" node that makes a file an external module. + * This is intended to be the first top-level import/export, + * but could be arbitrarily nested (e.g. `import.meta`). + */ /* @internal */ externalModuleIndicator: Node; // The first node that causes this file to be a CommonJS module /* @internal */ commonJsModuleIndicator: Node; From 161535bc848d750de4d266d3c2f829ac1662bbcc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 27 Apr 2018 17:51:18 -0700 Subject: [PATCH 220/229] Check for both 'module' and 'target'. --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 499beb6e87d..e43766d5456 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18812,7 +18812,7 @@ namespace ts { } function checkImportMetaProperty(node: MetaProperty) { - if (languageVersion < ScriptTarget.ESNext && moduleKind < ModuleKind.ESNext) { + if (languageVersion < ScriptTarget.ESNext || moduleKind < ModuleKind.ESNext) { error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_options); } const file = getSourceFileOfNode(node); From 12a3e39dcacc4180ab9beb17b35431ca1d598d83 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 27 Apr 2018 18:17:44 -0700 Subject: [PATCH 221/229] Specify ESNext module in test. --- tests/cases/conformance/es2019/importMeta/importMeta.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/cases/conformance/es2019/importMeta/importMeta.ts b/tests/cases/conformance/es2019/importMeta/importMeta.ts index c5022cf4abe..71d635a6534 100644 --- a/tests/cases/conformance/es2019/importMeta/importMeta.ts +++ b/tests/cases/conformance/es2019/importMeta/importMeta.ts @@ -1,5 +1,6 @@ // @target: esnext +// @module: esnext // @lib: es5,dom // @Filename: example.ts From e77da73efefa08b4b9eb973922e415daa8919ae1 Mon Sep 17 00:00:00 2001 From: Jordi Oliveras Rovira Date: Sat, 28 Apr 2018 11:53:02 +0200 Subject: [PATCH 222/229] Update issue template to match current nightly builds versions. --- issue_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/issue_template.md b/issue_template.md index dc2f223b72e..2e3895d4d7d 100644 --- a/issue_template.md +++ b/issue_template.md @@ -24,7 +24,7 @@ Please help us by doing the following steps before logging an issue: --> -**TypeScript Version:** 2.7.0-dev.201xxxxx +**TypeScript Version:** 2.9.0-dev.201xxxxx **Search Terms:** From 88dcdf9e3870cc58834de81a8ecb6b7533d3cb7c Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 28 Apr 2018 10:10:32 +0000 Subject: [PATCH 223/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 203d2c22ab9..2690ba4fe89 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1260,6 +1260,15 @@ + + + + + + + + + @@ -6513,6 +6522,15 @@ + + + + + + + + + @@ -8763,6 +8781,15 @@ + + + + + + + + + From 5a7eb1cbc89b8d850b4bc57a4dd72ca1109cc03b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 28 Apr 2018 08:24:41 -0700 Subject: [PATCH 224/229] Fix typo --- src/compiler/checker.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f0cbd70ed9c..22c8add26de 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8250,7 +8250,7 @@ namespace ts { return includes; } - function removeRedundantPrimtiveTypes(types: Type[], includes: TypeFlags) { + function removeRedundantPrimitiveTypes(types: Type[], includes: TypeFlags) { let i = types.length; while (i > 0) { i--; @@ -8264,6 +8264,7 @@ namespace ts { } } } + // We normalize combinations of intersection and union types based on the distributive property of the '&' // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection // types with union type constituents into equivalent union types with intersection type constituents and @@ -8289,7 +8290,7 @@ namespace ts { if (includes & TypeFlags.String && includes & TypeFlags.StringLiteral || includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral || includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) { - removeRedundantPrimtiveTypes(typeSet, includes); + removeRedundantPrimitiveTypes(typeSet, includes); } if (includes & TypeFlags.EmptyObject && !(includes & TypeFlags.Object)) { typeSet.push(emptyObjectType); From db9685c6455172800ff4977023d115a8fc948369 Mon Sep 17 00:00:00 2001 From: csigs Date: Sat, 28 Apr 2018 22:10:35 +0000 Subject: [PATCH 225/229] LEGO: check in for master to temporary branch. --- .../diagnosticMessages.generated.json.lcl | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index 546572f66c2..1cfc21834fe 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1251,6 +1251,15 @@ + + + + + + + + + @@ -6507,6 +6516,9 @@ + + + @@ -8760,6 +8772,15 @@ + + + + + + + + + From 4e401ca3616841d3636b8dcbbee9405fdcfaec81 Mon Sep 17 00:00:00 2001 From: Ken703 Date: Sat, 28 Apr 2018 19:59:41 -0400 Subject: [PATCH 226/229] update string template rule and test --- src/services/formatting/rules.ts | 7 ++----- .../formatNoSpaceBetweenClosingParenAndTemplateString.ts | 4 +++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 6f15135982b..a658cc41c65 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -126,11 +126,8 @@ namespace ts.formatting { rule("SpaceBetweenAsyncAndOpenParen", SyntaxKind.AsyncKeyword, SyntaxKind.OpenParenToken, [isArrowFunctionContext, isNonJsxSameLineTokenContext], RuleAction.Space), rule("SpaceBetweenAsyncAndFunctionKeyword", SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space), - // template string - rule("NoSpaceBetweenTagAndTemplateString", SyntaxKind.Identifier, [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete), - - // No space between closing parenthesis and template string - rule("NoSpaceBetweenCloseParenAndTemplateString", SyntaxKind.CloseParenToken, SyntaxKind.NoSubstitutionTemplateLiteral, [isNonJsxSameLineTokenContext], RuleAction.Delete), + // Template string + rule("NoSpaceBetweenTagAndTemplateString", [SyntaxKind.Identifier, SyntaxKind.CloseParenToken], [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete), // JSX opening elements rule("SpaceBeforeJsxAttribute", anyToken, SyntaxKind.Identifier, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], RuleAction.Space), diff --git a/tests/cases/fourslash/formatNoSpaceBetweenClosingParenAndTemplateString.ts b/tests/cases/fourslash/formatNoSpaceBetweenClosingParenAndTemplateString.ts index 47de1fac5d6..259252b6cb0 100644 --- a/tests/cases/fourslash/formatNoSpaceBetweenClosingParenAndTemplateString.ts +++ b/tests/cases/fourslash/formatNoSpaceBetweenClosingParenAndTemplateString.ts @@ -2,9 +2,11 @@ //// foo() `abc`; //// bar()`def`; +//// baz()`a${x}b`; format.document(); verify.currentFileContentIs( `foo()\`abc\`; -bar()\`def\`;` +bar()\`def\`; +baz()\`a\${x}b\`;` ); From fc2f16ca3c85788f1c734454604f103b2dbc4c10 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 29 Apr 2018 07:46:57 -0700 Subject: [PATCH 227/229] Treat unconstrained T[K] the same as unconstrained T --- src/compiler/checker.ts | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c6c5c0d6f02..ae59997b7a2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10670,23 +10670,8 @@ namespace ts { } } - if (source.flags & TypeFlags.TypeParameter) { - let constraint = getConstraintForRelation(source); - // A type parameter with no constraint is not related to the non-primitive object type. - if (constraint || !(target.flags & TypeFlags.NonPrimitive)) { - if (!constraint || constraint.flags & TypeFlags.Any) { - constraint = emptyObjectType; - } - // Report constraint errors only if the constraint is not the empty object type - const reportConstraintErrors = reportErrors && constraint !== emptyObjectType; - if (result = isRelatedTo(constraint, target, reportConstraintErrors)) { - errorInfo = saveErrorInfo; - return result; - } - } - } - else if (source.flags & TypeFlags.IndexedAccess) { - if (target.flags & TypeFlags.IndexedAccess) { + if (source.flags & TypeFlags.TypeVariable) { + if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) { // A type S[K] is related to a type T[J] if S is related to T and K is related to J. if (result = isRelatedTo((source).objectType, (target).objectType, reportErrors)) { result &= isRelatedTo((source).indexType, (target).indexType, reportErrors); @@ -10696,11 +10681,15 @@ namespace ts { return result; } } - // A type S[K] is related to a type T if C is related to T, where C is the - // constraint of S[K]. - const constraint = getConstraintForRelation(source); - if (constraint) { - if (result = isRelatedTo(constraint, target, reportErrors)) { + let constraint = getConstraintForRelation(source); + // A type variable with no constraint is not related to the non-primitive object type. + if (constraint || !(target.flags & TypeFlags.NonPrimitive)) { + if (!constraint || constraint.flags & TypeFlags.Any) { + constraint = emptyObjectType; + } + // Report constraint errors only if the constraint is not the empty object type + const reportConstraintErrors = reportErrors && constraint !== emptyObjectType; + if (result = isRelatedTo(constraint, target, reportConstraintErrors)) { errorInfo = saveErrorInfo; return result; } From 936444ad7be03e7358e2a7b0b9f5da6cbe195fe3 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 29 Apr 2018 07:55:23 -0700 Subject: [PATCH 228/229] Add tests --- .../types/keyof/keyofAndIndexedAccess.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index 23e5cd6a66e..83687e8c872 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -321,6 +321,20 @@ function f90(x1: S2[keyof S2], x2: T[keyof S2] x4.length; } +function f91(x: T, y: T[keyof T], z: T[K]) { + let a: {}; + a = x; + a = y; + a = z; +} + +function f92(x: T, y: T[keyof T], z: T[K]) { + let a: {} | null | undefined; + a = x; + a = y; + a = z; +} + // Repros from #12011 class Base { @@ -594,3 +608,24 @@ type DynamicDBRecord = ({ dynamicField: number } | { dynami function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { return record[flags[0]]; } + +// Repro from #21368 + +interface I { + foo: string; +} + +declare function take(p: T): void; + +function fn(o: T, k: K) { + take<{} | null | undefined>(o[k]); + take(o[k]); +} + +// Repro from #23133 + +class Unbounded { + foo(x: T[keyof T]) { + let y: {} | undefined | null = x; + } +} From f46040bdabf09f96a7455acb07d444a9bd359c5a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 29 Apr 2018 07:55:28 -0700 Subject: [PATCH 229/229] Accept new baselines --- .../reference/keyofAndIndexedAccess.js | 70 ++ .../reference/keyofAndIndexedAccess.symbols | 1109 +++++++++-------- .../reference/keyofAndIndexedAccess.types | 128 ++ 3 files changed, 810 insertions(+), 497 deletions(-) diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index a343b1e24fc..3d222583ffd 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -319,6 +319,20 @@ function f90(x1: S2[keyof S2], x2: T[keyof S2] x4.length; } +function f91(x: T, y: T[keyof T], z: T[K]) { + let a: {}; + a = x; + a = y; + a = z; +} + +function f92(x: T, y: T[keyof T], z: T[K]) { + let a: {} | null | undefined; + a = x; + a = y; + a = z; +} + // Repros from #12011 class Base { @@ -592,6 +606,27 @@ type DynamicDBRecord = ({ dynamicField: number } | { dynami function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { return record[flags[0]]; } + +// Repro from #21368 + +interface I { + foo: string; +} + +declare function take(p: T): void; + +function fn(o: T, k: K) { + take<{} | null | undefined>(o[k]); + take(o[k]); +} + +// Repro from #23133 + +class Unbounded { + foo(x: T[keyof T]) { + let y: {} | undefined | null = x; + } +} //// [keyofAndIndexedAccess.js] @@ -830,6 +865,18 @@ function f90(x1, x2, x3, x4) { x3.length; x4.length; } +function f91(x, y, z) { + var a; + a = x; + a = y; + a = z; +} +function f92(x, y, z) { + var a; + a = x; + a = y; + a = z; +} // Repros from #12011 var Base = /** @class */ (function () { function Base() { @@ -986,6 +1033,19 @@ function getFlagsFromSimpleRecord(record, flags) { function getFlagsFromDynamicRecord(record, flags) { return record[flags[0]]; } +function fn(o, k) { + take(o[k]); + take(o[k]); +} +// Repro from #23133 +var Unbounded = /** @class */ (function () { + function Unbounded() { + } + Unbounded.prototype.foo = function (x) { + var y = x; + }; + return Unbounded; +}()); //// [keyofAndIndexedAccess.d.ts] @@ -1126,6 +1186,8 @@ declare type S2 = { b: string; }; declare function f90(x1: S2[keyof S2], x2: T[keyof S2], x3: S2[K], x4: T[K]): void; +declare function f91(x: T, y: T[keyof T], z: T[K]): void; +declare function f92(x: T, y: T[keyof T], z: T[K]): void; declare class Base { get(prop: K): this[K]; set(prop: K, value: this[K]): void; @@ -1298,3 +1360,11 @@ declare type DynamicDBRecord = ({ dynamicField: string; }) & DBBoolTable; declare function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]): DynamicDBRecord[Flag]; +interface I { + foo: string; +} +declare function take(p: T): void; +declare function fn(o: T, k: K): void; +declare class Unbounded { + foo(x: T[keyof T]): void; +} diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index 5c0b45d81fb..a40a2347d91 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -1239,884 +1239,999 @@ function f90(x1: S2[keyof S2], x2: T[keyof S2] >length : Symbol(String.length, Decl(lib.d.ts, --, --)) } +function f91(x: T, y: T[keyof T], z: T[K]) { +>f91 : Symbol(f91, Decl(keyofAndIndexedAccess.ts, 318, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 320, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 320, 15)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 320, 13)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 320, 35)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 320, 13)) +>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 320, 40)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 320, 13)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 320, 13)) +>z : Symbol(z, Decl(keyofAndIndexedAccess.ts, 320, 55)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 320, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 320, 15)) + + let a: {}; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 321, 7)) + + a = x; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 321, 7)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 320, 35)) + + a = y; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 321, 7)) +>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 320, 40)) + + a = z; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 321, 7)) +>z : Symbol(z, Decl(keyofAndIndexedAccess.ts, 320, 55)) +} + +function f92(x: T, y: T[keyof T], z: T[K]) { +>f92 : Symbol(f92, Decl(keyofAndIndexedAccess.ts, 325, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 327, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 327, 15)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 327, 13)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 327, 35)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 327, 13)) +>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 327, 40)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 327, 13)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 327, 13)) +>z : Symbol(z, Decl(keyofAndIndexedAccess.ts, 327, 55)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 327, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 327, 15)) + + let a: {} | null | undefined; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 328, 7)) + + a = x; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 328, 7)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 327, 35)) + + a = y; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 328, 7)) +>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 327, 40)) + + a = z; +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 328, 7)) +>z : Symbol(z, Decl(keyofAndIndexedAccess.ts, 327, 55)) +} + // Repros from #12011 class Base { ->Base : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 318, 1)) +>Base : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 332, 1)) get(prop: K) { ->get : Symbol(Base.get, Decl(keyofAndIndexedAccess.ts, 322, 12)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 323, 8)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 323, 30)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 323, 8)) +>get : Symbol(Base.get, Decl(keyofAndIndexedAccess.ts, 336, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 337, 8)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 337, 30)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 337, 8)) return this[prop]; ->this : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 318, 1)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 323, 30)) +>this : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 332, 1)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 337, 30)) } set(prop: K, value: this[K]) { ->set : Symbol(Base.set, Decl(keyofAndIndexedAccess.ts, 325, 5)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 326, 8)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 326, 30)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 326, 8)) ->value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 326, 38)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 326, 8)) +>set : Symbol(Base.set, Decl(keyofAndIndexedAccess.ts, 339, 5)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 340, 8)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 340, 30)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 340, 8)) +>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 340, 38)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 340, 8)) this[prop] = value; ->this : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 318, 1)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 326, 30)) ->value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 326, 38)) +>this : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 332, 1)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 340, 30)) +>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 340, 38)) } } class Person extends Base { ->Person : Symbol(Person, Decl(keyofAndIndexedAccess.ts, 329, 1)) ->Base : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 318, 1)) +>Person : Symbol(Person, Decl(keyofAndIndexedAccess.ts, 343, 1)) +>Base : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 332, 1)) parts: number; ->parts : Symbol(Person.parts, Decl(keyofAndIndexedAccess.ts, 331, 27)) +>parts : Symbol(Person.parts, Decl(keyofAndIndexedAccess.ts, 345, 27)) constructor(parts: number) { ->parts : Symbol(parts, Decl(keyofAndIndexedAccess.ts, 333, 16)) +>parts : Symbol(parts, Decl(keyofAndIndexedAccess.ts, 347, 16)) super(); ->super : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 318, 1)) +>super : Symbol(Base, Decl(keyofAndIndexedAccess.ts, 332, 1)) this.set("parts", parts); ->this.set : Symbol(Base.set, Decl(keyofAndIndexedAccess.ts, 325, 5)) ->this : Symbol(Person, Decl(keyofAndIndexedAccess.ts, 329, 1)) ->set : Symbol(Base.set, Decl(keyofAndIndexedAccess.ts, 325, 5)) ->parts : Symbol(parts, Decl(keyofAndIndexedAccess.ts, 333, 16)) +>this.set : Symbol(Base.set, Decl(keyofAndIndexedAccess.ts, 339, 5)) +>this : Symbol(Person, Decl(keyofAndIndexedAccess.ts, 343, 1)) +>set : Symbol(Base.set, Decl(keyofAndIndexedAccess.ts, 339, 5)) +>parts : Symbol(parts, Decl(keyofAndIndexedAccess.ts, 347, 16)) } getParts() { ->getParts : Symbol(Person.getParts, Decl(keyofAndIndexedAccess.ts, 336, 5)) +>getParts : Symbol(Person.getParts, Decl(keyofAndIndexedAccess.ts, 350, 5)) return this.get("parts") ->this.get : Symbol(Base.get, Decl(keyofAndIndexedAccess.ts, 322, 12)) ->this : Symbol(Person, Decl(keyofAndIndexedAccess.ts, 329, 1)) ->get : Symbol(Base.get, Decl(keyofAndIndexedAccess.ts, 322, 12)) +>this.get : Symbol(Base.get, Decl(keyofAndIndexedAccess.ts, 336, 12)) +>this : Symbol(Person, Decl(keyofAndIndexedAccess.ts, 343, 1)) +>get : Symbol(Base.get, Decl(keyofAndIndexedAccess.ts, 336, 12)) } } class OtherPerson { ->OtherPerson : Symbol(OtherPerson, Decl(keyofAndIndexedAccess.ts, 340, 1)) +>OtherPerson : Symbol(OtherPerson, Decl(keyofAndIndexedAccess.ts, 354, 1)) parts: number; ->parts : Symbol(OtherPerson.parts, Decl(keyofAndIndexedAccess.ts, 342, 19)) +>parts : Symbol(OtherPerson.parts, Decl(keyofAndIndexedAccess.ts, 356, 19)) constructor(parts: number) { ->parts : Symbol(parts, Decl(keyofAndIndexedAccess.ts, 344, 16)) +>parts : Symbol(parts, Decl(keyofAndIndexedAccess.ts, 358, 16)) setProperty(this, "parts", parts); >setProperty : Symbol(setProperty, Decl(keyofAndIndexedAccess.ts, 80, 1)) ->this : Symbol(OtherPerson, Decl(keyofAndIndexedAccess.ts, 340, 1)) ->parts : Symbol(parts, Decl(keyofAndIndexedAccess.ts, 344, 16)) +>this : Symbol(OtherPerson, Decl(keyofAndIndexedAccess.ts, 354, 1)) +>parts : Symbol(parts, Decl(keyofAndIndexedAccess.ts, 358, 16)) } getParts() { ->getParts : Symbol(OtherPerson.getParts, Decl(keyofAndIndexedAccess.ts, 346, 5)) +>getParts : Symbol(OtherPerson.getParts, Decl(keyofAndIndexedAccess.ts, 360, 5)) return getProperty(this, "parts") >getProperty : Symbol(getProperty, Decl(keyofAndIndexedAccess.ts, 76, 26)) ->this : Symbol(OtherPerson, Decl(keyofAndIndexedAccess.ts, 340, 1)) +>this : Symbol(OtherPerson, Decl(keyofAndIndexedAccess.ts, 354, 1)) } } // Modified repro from #12544 function path(obj: T, key1: K1): T[K1]; ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 354, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 354, 16)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 354, 14)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 354, 37)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 354, 14)) ->key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 354, 44)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 354, 16)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 354, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 354, 16)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 368, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 368, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 368, 14)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 368, 37)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 368, 14)) +>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 368, 44)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 368, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 368, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 368, 16)) function path(obj: T, key1: K1, key2: K2): T[K1][K2]; ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 355, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 355, 16)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 355, 14)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 355, 36)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 355, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 355, 16)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 355, 61)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 355, 14)) ->key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 355, 68)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 355, 16)) ->key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 355, 78)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 355, 36)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 355, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 355, 16)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 355, 36)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 369, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 369, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 369, 14)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 369, 36)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 369, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 369, 16)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 369, 61)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 369, 14)) +>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 369, 68)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 369, 16)) +>key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 369, 78)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 369, 36)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 369, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 369, 16)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 369, 36)) function path(obj: T, key1: K1, key2: K2, key3: K3): T[K1][K2][K3]; ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 356, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 356, 16)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 356, 14)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 356, 36)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 356, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 356, 16)) ->K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 356, 60)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 356, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 356, 16)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 356, 36)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 356, 89)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 356, 14)) ->key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 356, 96)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 356, 16)) ->key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 356, 106)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 356, 36)) ->key3 : Symbol(key3, Decl(keyofAndIndexedAccess.ts, 356, 116)) ->K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 356, 60)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 356, 14)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 356, 16)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 356, 36)) ->K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 356, 60)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 370, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 370, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 370, 14)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 370, 36)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 370, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 370, 16)) +>K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 370, 60)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 370, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 370, 16)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 370, 36)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 370, 89)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 370, 14)) +>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 370, 96)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 370, 16)) +>key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 370, 106)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 370, 36)) +>key3 : Symbol(key3, Decl(keyofAndIndexedAccess.ts, 370, 116)) +>K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 370, 60)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 370, 14)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 370, 16)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 370, 36)) +>K3 : Symbol(K3, Decl(keyofAndIndexedAccess.ts, 370, 60)) function path(obj: any, ...keys: (string | number)[]): any; ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 357, 14)) ->keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 357, 23)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 371, 14)) +>keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 371, 23)) function path(obj: any, ...keys: (string | number)[]): any { ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 358, 14)) ->keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 358, 23)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 372, 14)) +>keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 372, 23)) let result = obj; ->result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 359, 7)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 358, 14)) +>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 373, 7)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 372, 14)) for (let k of keys) { ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 360, 12)) ->keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 358, 23)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 374, 12)) +>keys : Symbol(keys, Decl(keyofAndIndexedAccess.ts, 372, 23)) result = result[k]; ->result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 359, 7)) ->result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 359, 7)) ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 360, 12)) +>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 373, 7)) +>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 373, 7)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 374, 12)) } return result; ->result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 359, 7)) +>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 373, 7)) } type Thing = { ->Thing : Symbol(Thing, Decl(keyofAndIndexedAccess.ts, 364, 1)) +>Thing : Symbol(Thing, Decl(keyofAndIndexedAccess.ts, 378, 1)) a: { x: number, y: string }, ->a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 366, 14)) ->x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 367, 8)) ->y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 367, 19)) +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 380, 14)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 381, 8)) +>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 381, 19)) b: boolean ->b : Symbol(b, Decl(keyofAndIndexedAccess.ts, 367, 32)) +>b : Symbol(b, Decl(keyofAndIndexedAccess.ts, 381, 32)) }; function f1(thing: Thing) { ->f1 : Symbol(f1, Decl(keyofAndIndexedAccess.ts, 369, 2)) ->thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 372, 12)) ->Thing : Symbol(Thing, Decl(keyofAndIndexedAccess.ts, 364, 1)) +>f1 : Symbol(f1, Decl(keyofAndIndexedAccess.ts, 383, 2)) +>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 386, 12)) +>Thing : Symbol(Thing, Decl(keyofAndIndexedAccess.ts, 378, 1)) let x1 = path(thing, 'a'); // { x: number, y: string } ->x1 : Symbol(x1, Decl(keyofAndIndexedAccess.ts, 373, 7)) ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 372, 12)) +>x1 : Symbol(x1, Decl(keyofAndIndexedAccess.ts, 387, 7)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 386, 12)) let x2 = path(thing, 'a', 'y'); // string ->x2 : Symbol(x2, Decl(keyofAndIndexedAccess.ts, 374, 7)) ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 372, 12)) +>x2 : Symbol(x2, Decl(keyofAndIndexedAccess.ts, 388, 7)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 386, 12)) let x3 = path(thing, 'b'); // boolean ->x3 : Symbol(x3, Decl(keyofAndIndexedAccess.ts, 375, 7)) ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 372, 12)) +>x3 : Symbol(x3, Decl(keyofAndIndexedAccess.ts, 389, 7)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 386, 12)) let x4 = path(thing, ...['a', 'x']); // any ->x4 : Symbol(x4, Decl(keyofAndIndexedAccess.ts, 376, 7)) ->path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 350, 1), Decl(keyofAndIndexedAccess.ts, 354, 62), Decl(keyofAndIndexedAccess.ts, 355, 100), Decl(keyofAndIndexedAccess.ts, 356, 142), Decl(keyofAndIndexedAccess.ts, 357, 59)) ->thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 372, 12)) +>x4 : Symbol(x4, Decl(keyofAndIndexedAccess.ts, 390, 7)) +>path : Symbol(path, Decl(keyofAndIndexedAccess.ts, 364, 1), Decl(keyofAndIndexedAccess.ts, 368, 62), Decl(keyofAndIndexedAccess.ts, 369, 100), Decl(keyofAndIndexedAccess.ts, 370, 142), Decl(keyofAndIndexedAccess.ts, 371, 59)) +>thing : Symbol(thing, Decl(keyofAndIndexedAccess.ts, 386, 12)) } // Repro from comment in #12114 const assignTo2 = (object: T, key1: K1, key2: K2) => ->assignTo2 : Symbol(assignTo2, Decl(keyofAndIndexedAccess.ts, 381, 5)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 381, 19)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 381, 21)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 381, 19)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 381, 41)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 381, 19)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 381, 21)) ->object : Symbol(object, Decl(keyofAndIndexedAccess.ts, 381, 66)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 381, 19)) ->key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 381, 76)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 381, 21)) ->key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 381, 86)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 381, 41)) +>assignTo2 : Symbol(assignTo2, Decl(keyofAndIndexedAccess.ts, 395, 5)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 395, 19)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 395, 21)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 395, 19)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 395, 41)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 395, 19)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 395, 21)) +>object : Symbol(object, Decl(keyofAndIndexedAccess.ts, 395, 66)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 395, 19)) +>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 395, 76)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 395, 21)) +>key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 395, 86)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 395, 41)) (value: T[K1][K2]) => object[key1][key2] = value; ->value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 382, 5)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 381, 19)) ->K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 381, 21)) ->K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 381, 41)) ->object : Symbol(object, Decl(keyofAndIndexedAccess.ts, 381, 66)) ->key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 381, 76)) ->key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 381, 86)) ->value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 382, 5)) +>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 396, 5)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 395, 19)) +>K1 : Symbol(K1, Decl(keyofAndIndexedAccess.ts, 395, 21)) +>K2 : Symbol(K2, Decl(keyofAndIndexedAccess.ts, 395, 41)) +>object : Symbol(object, Decl(keyofAndIndexedAccess.ts, 395, 66)) +>key1 : Symbol(key1, Decl(keyofAndIndexedAccess.ts, 395, 76)) +>key2 : Symbol(key2, Decl(keyofAndIndexedAccess.ts, 395, 86)) +>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 396, 5)) // Modified repro from #12573 declare function one(handler: (t: T) => void): T ->one : Symbol(one, Decl(keyofAndIndexedAccess.ts, 382, 53)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 386, 21)) ->handler : Symbol(handler, Decl(keyofAndIndexedAccess.ts, 386, 24)) ->t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 386, 34)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 386, 21)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 386, 21)) +>one : Symbol(one, Decl(keyofAndIndexedAccess.ts, 396, 53)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 400, 21)) +>handler : Symbol(handler, Decl(keyofAndIndexedAccess.ts, 400, 24)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 400, 34)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 400, 21)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 400, 21)) var empty = one(() => {}) // inferred as {}, expected ->empty : Symbol(empty, Decl(keyofAndIndexedAccess.ts, 387, 3)) ->one : Symbol(one, Decl(keyofAndIndexedAccess.ts, 382, 53)) +>empty : Symbol(empty, Decl(keyofAndIndexedAccess.ts, 401, 3)) +>one : Symbol(one, Decl(keyofAndIndexedAccess.ts, 396, 53)) type Handlers = { [K in keyof T]: (t: T[K]) => void } ->Handlers : Symbol(Handlers, Decl(keyofAndIndexedAccess.ts, 387, 25)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 389, 14)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 389, 22)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 389, 14)) ->t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 389, 38)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 389, 14)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 389, 22)) +>Handlers : Symbol(Handlers, Decl(keyofAndIndexedAccess.ts, 401, 25)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 403, 14)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 403, 22)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 403, 14)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 403, 38)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 403, 14)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 403, 22)) declare function on(handlerHash: Handlers): T ->on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 389, 56)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 390, 20)) ->handlerHash : Symbol(handlerHash, Decl(keyofAndIndexedAccess.ts, 390, 23)) ->Handlers : Symbol(Handlers, Decl(keyofAndIndexedAccess.ts, 387, 25)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 390, 20)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 390, 20)) +>on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 403, 56)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 404, 20)) +>handlerHash : Symbol(handlerHash, Decl(keyofAndIndexedAccess.ts, 404, 23)) +>Handlers : Symbol(Handlers, Decl(keyofAndIndexedAccess.ts, 401, 25)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 404, 20)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 404, 20)) var hashOfEmpty1 = on({ test: () => {} }); // {} ->hashOfEmpty1 : Symbol(hashOfEmpty1, Decl(keyofAndIndexedAccess.ts, 391, 3)) ->on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 389, 56)) ->test : Symbol(test, Decl(keyofAndIndexedAccess.ts, 391, 23)) +>hashOfEmpty1 : Symbol(hashOfEmpty1, Decl(keyofAndIndexedAccess.ts, 405, 3)) +>on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 403, 56)) +>test : Symbol(test, Decl(keyofAndIndexedAccess.ts, 405, 23)) var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean } ->hashOfEmpty2 : Symbol(hashOfEmpty2, Decl(keyofAndIndexedAccess.ts, 392, 3)) ->on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 389, 56)) ->test : Symbol(test, Decl(keyofAndIndexedAccess.ts, 392, 23)) ->x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 392, 31)) +>hashOfEmpty2 : Symbol(hashOfEmpty2, Decl(keyofAndIndexedAccess.ts, 406, 3)) +>on : Symbol(on, Decl(keyofAndIndexedAccess.ts, 403, 56)) +>test : Symbol(test, Decl(keyofAndIndexedAccess.ts, 406, 23)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 406, 31)) // Repro from #12624 interface Options1 { ->Options1 : Symbol(Options1, Decl(keyofAndIndexedAccess.ts, 392, 52)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 396, 19)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 396, 24)) +>Options1 : Symbol(Options1, Decl(keyofAndIndexedAccess.ts, 406, 52)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 410, 19)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 410, 24)) data?: Data ->data : Symbol(Options1.data, Decl(keyofAndIndexedAccess.ts, 396, 36)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 396, 19)) +>data : Symbol(Options1.data, Decl(keyofAndIndexedAccess.ts, 410, 36)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 410, 19)) computed?: Computed; ->computed : Symbol(Options1.computed, Decl(keyofAndIndexedAccess.ts, 397, 15)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 396, 24)) +>computed : Symbol(Options1.computed, Decl(keyofAndIndexedAccess.ts, 411, 15)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 410, 24)) } declare class Component1 { ->Component1 : Symbol(Component1, Decl(keyofAndIndexedAccess.ts, 399, 1)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 401, 25)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 401, 30)) +>Component1 : Symbol(Component1, Decl(keyofAndIndexedAccess.ts, 413, 1)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 415, 25)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 415, 30)) constructor(options: Options1); ->options : Symbol(options, Decl(keyofAndIndexedAccess.ts, 402, 16)) ->Options1 : Symbol(Options1, Decl(keyofAndIndexedAccess.ts, 392, 52)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 401, 25)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 401, 30)) +>options : Symbol(options, Decl(keyofAndIndexedAccess.ts, 416, 16)) +>Options1 : Symbol(Options1, Decl(keyofAndIndexedAccess.ts, 406, 52)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 415, 25)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 415, 30)) get(key: K): (Data & Computed)[K]; ->get : Symbol(Component1.get, Decl(keyofAndIndexedAccess.ts, 402, 51)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 403, 8)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 401, 25)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 401, 30)) ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 403, 43)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 403, 8)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 401, 25)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 401, 30)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 403, 8)) +>get : Symbol(Component1.get, Decl(keyofAndIndexedAccess.ts, 416, 51)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 417, 8)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 415, 25)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 415, 30)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 417, 43)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 417, 8)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 415, 25)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 415, 30)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 417, 8)) } let c1 = new Component1({ ->c1 : Symbol(c1, Decl(keyofAndIndexedAccess.ts, 406, 3)) ->Component1 : Symbol(Component1, Decl(keyofAndIndexedAccess.ts, 399, 1)) +>c1 : Symbol(c1, Decl(keyofAndIndexedAccess.ts, 420, 3)) +>Component1 : Symbol(Component1, Decl(keyofAndIndexedAccess.ts, 413, 1)) data: { ->data : Symbol(data, Decl(keyofAndIndexedAccess.ts, 406, 25)) +>data : Symbol(data, Decl(keyofAndIndexedAccess.ts, 420, 25)) hello: "" ->hello : Symbol(hello, Decl(keyofAndIndexedAccess.ts, 407, 11)) +>hello : Symbol(hello, Decl(keyofAndIndexedAccess.ts, 421, 11)) } }); c1.get("hello"); ->c1.get : Symbol(Component1.get, Decl(keyofAndIndexedAccess.ts, 402, 51)) ->c1 : Symbol(c1, Decl(keyofAndIndexedAccess.ts, 406, 3)) ->get : Symbol(Component1.get, Decl(keyofAndIndexedAccess.ts, 402, 51)) +>c1.get : Symbol(Component1.get, Decl(keyofAndIndexedAccess.ts, 416, 51)) +>c1 : Symbol(c1, Decl(keyofAndIndexedAccess.ts, 420, 3)) +>get : Symbol(Component1.get, Decl(keyofAndIndexedAccess.ts, 416, 51)) // Repro from #12625 interface Options2 { ->Options2 : Symbol(Options2, Decl(keyofAndIndexedAccess.ts, 412, 16)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 416, 19)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 416, 24)) +>Options2 : Symbol(Options2, Decl(keyofAndIndexedAccess.ts, 426, 16)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 430, 19)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 430, 24)) data?: Data ->data : Symbol(Options2.data, Decl(keyofAndIndexedAccess.ts, 416, 36)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 416, 19)) +>data : Symbol(Options2.data, Decl(keyofAndIndexedAccess.ts, 430, 36)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 430, 19)) computed?: Computed; ->computed : Symbol(Options2.computed, Decl(keyofAndIndexedAccess.ts, 417, 15)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 416, 24)) +>computed : Symbol(Options2.computed, Decl(keyofAndIndexedAccess.ts, 431, 15)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 430, 24)) } declare class Component2 { ->Component2 : Symbol(Component2, Decl(keyofAndIndexedAccess.ts, 419, 1)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 421, 25)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 421, 30)) +>Component2 : Symbol(Component2, Decl(keyofAndIndexedAccess.ts, 433, 1)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 435, 25)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 435, 30)) constructor(options: Options2); ->options : Symbol(options, Decl(keyofAndIndexedAccess.ts, 422, 16)) ->Options2 : Symbol(Options2, Decl(keyofAndIndexedAccess.ts, 412, 16)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 421, 25)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 421, 30)) +>options : Symbol(options, Decl(keyofAndIndexedAccess.ts, 436, 16)) +>Options2 : Symbol(Options2, Decl(keyofAndIndexedAccess.ts, 426, 16)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 435, 25)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 435, 30)) get(key: K): (Data & Computed)[K]; ->get : Symbol(Component2.get, Decl(keyofAndIndexedAccess.ts, 422, 51)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 423, 8)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 421, 25)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 421, 30)) ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 423, 47)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 423, 8)) ->Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 421, 25)) ->Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 421, 30)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 423, 8)) +>get : Symbol(Component2.get, Decl(keyofAndIndexedAccess.ts, 436, 51)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 437, 8)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 435, 25)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 435, 30)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 437, 47)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 437, 8)) +>Data : Symbol(Data, Decl(keyofAndIndexedAccess.ts, 435, 25)) +>Computed : Symbol(Computed, Decl(keyofAndIndexedAccess.ts, 435, 30)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 437, 8)) } // Repro from #12641 interface R { ->R : Symbol(R, Decl(keyofAndIndexedAccess.ts, 424, 1)) +>R : Symbol(R, Decl(keyofAndIndexedAccess.ts, 438, 1)) p: number; ->p : Symbol(R.p, Decl(keyofAndIndexedAccess.ts, 428, 13)) +>p : Symbol(R.p, Decl(keyofAndIndexedAccess.ts, 442, 13)) } function f(p: K) { ->f : Symbol(f, Decl(keyofAndIndexedAccess.ts, 430, 1)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 432, 11)) ->R : Symbol(R, Decl(keyofAndIndexedAccess.ts, 424, 1)) ->p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 432, 30)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 432, 11)) +>f : Symbol(f, Decl(keyofAndIndexedAccess.ts, 444, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 446, 11)) +>R : Symbol(R, Decl(keyofAndIndexedAccess.ts, 438, 1)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 446, 30)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 446, 11)) let a: any; ->a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 433, 7)) +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 447, 7)) a[p].add; // any ->a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 433, 7)) ->p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 432, 30)) +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 447, 7)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 446, 30)) } // Repro from #12651 type MethodDescriptor = { ->MethodDescriptor : Symbol(MethodDescriptor, Decl(keyofAndIndexedAccess.ts, 435, 1)) +>MethodDescriptor : Symbol(MethodDescriptor, Decl(keyofAndIndexedAccess.ts, 449, 1)) name: string; ->name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 439, 25)) +>name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 453, 25)) args: any[]; ->args : Symbol(args, Decl(keyofAndIndexedAccess.ts, 440, 14)) +>args : Symbol(args, Decl(keyofAndIndexedAccess.ts, 454, 14)) returnValue: any; ->returnValue : Symbol(returnValue, Decl(keyofAndIndexedAccess.ts, 441, 13)) +>returnValue : Symbol(returnValue, Decl(keyofAndIndexedAccess.ts, 455, 13)) } declare function dispatchMethod(name: M['name'], args: M['args']): M['returnValue']; ->dispatchMethod : Symbol(dispatchMethod, Decl(keyofAndIndexedAccess.ts, 443, 1)) ->M : Symbol(M, Decl(keyofAndIndexedAccess.ts, 445, 32)) ->MethodDescriptor : Symbol(MethodDescriptor, Decl(keyofAndIndexedAccess.ts, 435, 1)) ->name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 445, 60)) ->M : Symbol(M, Decl(keyofAndIndexedAccess.ts, 445, 32)) ->args : Symbol(args, Decl(keyofAndIndexedAccess.ts, 445, 76)) ->M : Symbol(M, Decl(keyofAndIndexedAccess.ts, 445, 32)) ->M : Symbol(M, Decl(keyofAndIndexedAccess.ts, 445, 32)) +>dispatchMethod : Symbol(dispatchMethod, Decl(keyofAndIndexedAccess.ts, 457, 1)) +>M : Symbol(M, Decl(keyofAndIndexedAccess.ts, 459, 32)) +>MethodDescriptor : Symbol(MethodDescriptor, Decl(keyofAndIndexedAccess.ts, 449, 1)) +>name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 459, 60)) +>M : Symbol(M, Decl(keyofAndIndexedAccess.ts, 459, 32)) +>args : Symbol(args, Decl(keyofAndIndexedAccess.ts, 459, 76)) +>M : Symbol(M, Decl(keyofAndIndexedAccess.ts, 459, 32)) +>M : Symbol(M, Decl(keyofAndIndexedAccess.ts, 459, 32)) type SomeMethodDescriptor = { ->SomeMethodDescriptor : Symbol(SomeMethodDescriptor, Decl(keyofAndIndexedAccess.ts, 445, 112)) +>SomeMethodDescriptor : Symbol(SomeMethodDescriptor, Decl(keyofAndIndexedAccess.ts, 459, 112)) name: "someMethod"; ->name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 447, 29)) +>name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 461, 29)) args: [string, number]; ->args : Symbol(args, Decl(keyofAndIndexedAccess.ts, 448, 20)) +>args : Symbol(args, Decl(keyofAndIndexedAccess.ts, 462, 20)) returnValue: string[]; ->returnValue : Symbol(returnValue, Decl(keyofAndIndexedAccess.ts, 449, 24)) +>returnValue : Symbol(returnValue, Decl(keyofAndIndexedAccess.ts, 463, 24)) } let result = dispatchMethod("someMethod", ["hello", 35]); ->result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 453, 3)) ->dispatchMethod : Symbol(dispatchMethod, Decl(keyofAndIndexedAccess.ts, 443, 1)) ->SomeMethodDescriptor : Symbol(SomeMethodDescriptor, Decl(keyofAndIndexedAccess.ts, 445, 112)) +>result : Symbol(result, Decl(keyofAndIndexedAccess.ts, 467, 3)) +>dispatchMethod : Symbol(dispatchMethod, Decl(keyofAndIndexedAccess.ts, 457, 1)) +>SomeMethodDescriptor : Symbol(SomeMethodDescriptor, Decl(keyofAndIndexedAccess.ts, 459, 112)) // Repro from #13073 type KeyTypes = "a" | "b" ->KeyTypes : Symbol(KeyTypes, Decl(keyofAndIndexedAccess.ts, 453, 79)) +>KeyTypes : Symbol(KeyTypes, Decl(keyofAndIndexedAccess.ts, 467, 79)) let MyThingy: { [key in KeyTypes]: string[] }; ->MyThingy : Symbol(MyThingy, Decl(keyofAndIndexedAccess.ts, 458, 3)) ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 458, 17)) ->KeyTypes : Symbol(KeyTypes, Decl(keyofAndIndexedAccess.ts, 453, 79)) +>MyThingy : Symbol(MyThingy, Decl(keyofAndIndexedAccess.ts, 472, 3)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 472, 17)) +>KeyTypes : Symbol(KeyTypes, Decl(keyofAndIndexedAccess.ts, 467, 79)) function addToMyThingy(key: S) { ->addToMyThingy : Symbol(addToMyThingy, Decl(keyofAndIndexedAccess.ts, 458, 46)) ->S : Symbol(S, Decl(keyofAndIndexedAccess.ts, 460, 23)) ->KeyTypes : Symbol(KeyTypes, Decl(keyofAndIndexedAccess.ts, 453, 79)) ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 460, 43)) ->S : Symbol(S, Decl(keyofAndIndexedAccess.ts, 460, 23)) +>addToMyThingy : Symbol(addToMyThingy, Decl(keyofAndIndexedAccess.ts, 472, 46)) +>S : Symbol(S, Decl(keyofAndIndexedAccess.ts, 474, 23)) +>KeyTypes : Symbol(KeyTypes, Decl(keyofAndIndexedAccess.ts, 467, 79)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 474, 43)) +>S : Symbol(S, Decl(keyofAndIndexedAccess.ts, 474, 23)) MyThingy[key].push("a"); >MyThingy[key].push : Symbol(Array.push, Decl(lib.d.ts, --, --)) ->MyThingy : Symbol(MyThingy, Decl(keyofAndIndexedAccess.ts, 458, 3)) ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 460, 43)) +>MyThingy : Symbol(MyThingy, Decl(keyofAndIndexedAccess.ts, 472, 3)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 474, 43)) >push : Symbol(Array.push, Decl(lib.d.ts, --, --)) } // Repro from #13102 type Handler = { ->Handler : Symbol(Handler, Decl(keyofAndIndexedAccess.ts, 462, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 466, 13)) +>Handler : Symbol(Handler, Decl(keyofAndIndexedAccess.ts, 476, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 480, 13)) onChange: (name: keyof T) => void; ->onChange : Symbol(onChange, Decl(keyofAndIndexedAccess.ts, 466, 19)) ->name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 467, 15)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 466, 13)) +>onChange : Symbol(onChange, Decl(keyofAndIndexedAccess.ts, 480, 19)) +>name : Symbol(name, Decl(keyofAndIndexedAccess.ts, 481, 15)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 480, 13)) }; function onChangeGenericFunction(handler: Handler) { ->onChangeGenericFunction : Symbol(onChangeGenericFunction, Decl(keyofAndIndexedAccess.ts, 468, 2)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 470, 33)) ->handler : Symbol(handler, Decl(keyofAndIndexedAccess.ts, 470, 36)) ->Handler : Symbol(Handler, Decl(keyofAndIndexedAccess.ts, 462, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 470, 33)) ->preset : Symbol(preset, Decl(keyofAndIndexedAccess.ts, 470, 58)) +>onChangeGenericFunction : Symbol(onChangeGenericFunction, Decl(keyofAndIndexedAccess.ts, 482, 2)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 484, 33)) +>handler : Symbol(handler, Decl(keyofAndIndexedAccess.ts, 484, 36)) +>Handler : Symbol(Handler, Decl(keyofAndIndexedAccess.ts, 476, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 484, 33)) +>preset : Symbol(preset, Decl(keyofAndIndexedAccess.ts, 484, 58)) handler.onChange('preset') ->handler.onChange : Symbol(onChange, Decl(keyofAndIndexedAccess.ts, 466, 19)) ->handler : Symbol(handler, Decl(keyofAndIndexedAccess.ts, 470, 36)) ->onChange : Symbol(onChange, Decl(keyofAndIndexedAccess.ts, 466, 19)) +>handler.onChange : Symbol(onChange, Decl(keyofAndIndexedAccess.ts, 480, 19)) +>handler : Symbol(handler, Decl(keyofAndIndexedAccess.ts, 484, 36)) +>onChange : Symbol(onChange, Decl(keyofAndIndexedAccess.ts, 480, 19)) } // Repro from #13285 function updateIds, K extends string>( ->updateIds : Symbol(updateIds, Decl(keyofAndIndexedAccess.ts, 472, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 476, 19)) +>updateIds : Symbol(updateIds, Decl(keyofAndIndexedAccess.ts, 486, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 490, 19)) >Record : Symbol(Record, Decl(lib.d.ts, --, --)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 476, 47)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 476, 47)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 490, 47)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 490, 47)) obj: T, ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 476, 66)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 476, 19)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 490, 66)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 490, 19)) idFields: K[], ->idFields : Symbol(idFields, Decl(keyofAndIndexedAccess.ts, 477, 11)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 476, 47)) +>idFields : Symbol(idFields, Decl(keyofAndIndexedAccess.ts, 491, 11)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 490, 47)) idMapping: { [oldId: string]: string } ->idMapping : Symbol(idMapping, Decl(keyofAndIndexedAccess.ts, 478, 18)) ->oldId : Symbol(oldId, Decl(keyofAndIndexedAccess.ts, 479, 18)) +>idMapping : Symbol(idMapping, Decl(keyofAndIndexedAccess.ts, 492, 18)) +>oldId : Symbol(oldId, Decl(keyofAndIndexedAccess.ts, 493, 18)) ): Record { >Record : Symbol(Record, Decl(lib.d.ts, --, --)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 476, 47)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 490, 47)) for (const idField of idFields) { ->idField : Symbol(idField, Decl(keyofAndIndexedAccess.ts, 481, 14)) ->idFields : Symbol(idFields, Decl(keyofAndIndexedAccess.ts, 477, 11)) +>idField : Symbol(idField, Decl(keyofAndIndexedAccess.ts, 495, 14)) +>idFields : Symbol(idFields, Decl(keyofAndIndexedAccess.ts, 491, 11)) const newId = idMapping[obj[idField]]; ->newId : Symbol(newId, Decl(keyofAndIndexedAccess.ts, 482, 13)) ->idMapping : Symbol(idMapping, Decl(keyofAndIndexedAccess.ts, 478, 18)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 476, 66)) ->idField : Symbol(idField, Decl(keyofAndIndexedAccess.ts, 481, 14)) +>newId : Symbol(newId, Decl(keyofAndIndexedAccess.ts, 496, 13)) +>idMapping : Symbol(idMapping, Decl(keyofAndIndexedAccess.ts, 492, 18)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 490, 66)) +>idField : Symbol(idField, Decl(keyofAndIndexedAccess.ts, 495, 14)) if (newId) { ->newId : Symbol(newId, Decl(keyofAndIndexedAccess.ts, 482, 13)) +>newId : Symbol(newId, Decl(keyofAndIndexedAccess.ts, 496, 13)) obj[idField] = newId; ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 476, 66)) ->idField : Symbol(idField, Decl(keyofAndIndexedAccess.ts, 481, 14)) ->newId : Symbol(newId, Decl(keyofAndIndexedAccess.ts, 482, 13)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 490, 66)) +>idField : Symbol(idField, Decl(keyofAndIndexedAccess.ts, 495, 14)) +>newId : Symbol(newId, Decl(keyofAndIndexedAccess.ts, 496, 13)) } } return obj; ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 476, 66)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 490, 66)) } // Repro from #13285 function updateIds2( ->updateIds2 : Symbol(updateIds2, Decl(keyofAndIndexedAccess.ts, 488, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 492, 20)) ->x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 492, 33)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 492, 54)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 492, 20)) +>updateIds2 : Symbol(updateIds2, Decl(keyofAndIndexedAccess.ts, 502, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 506, 20)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 506, 33)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 506, 54)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 506, 20)) obj: T, ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 492, 74)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 492, 20)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 506, 74)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 506, 20)) key: K, ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 493, 11)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 492, 54)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 507, 11)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 506, 54)) stringMap: { [oldId: string]: string } ->stringMap : Symbol(stringMap, Decl(keyofAndIndexedAccess.ts, 494, 11)) ->oldId : Symbol(oldId, Decl(keyofAndIndexedAccess.ts, 495, 18)) +>stringMap : Symbol(stringMap, Decl(keyofAndIndexedAccess.ts, 508, 11)) +>oldId : Symbol(oldId, Decl(keyofAndIndexedAccess.ts, 509, 18)) ) { var x = obj[key]; ->x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 497, 7)) ->obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 492, 74)) ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 493, 11)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 511, 7)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccess.ts, 506, 74)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 507, 11)) stringMap[x]; // Should be OK. ->stringMap : Symbol(stringMap, Decl(keyofAndIndexedAccess.ts, 494, 11)) ->x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 497, 7)) +>stringMap : Symbol(stringMap, Decl(keyofAndIndexedAccess.ts, 508, 11)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 511, 7)) } // Repro from #13514 declare function head>(list: T): T[0]; ->head : Symbol(head, Decl(keyofAndIndexedAccess.ts, 499, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 503, 22)) +>head : Symbol(head, Decl(keyofAndIndexedAccess.ts, 513, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 517, 22)) >Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->list : Symbol(list, Decl(keyofAndIndexedAccess.ts, 503, 44)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 503, 22)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 503, 22)) +>list : Symbol(list, Decl(keyofAndIndexedAccess.ts, 517, 44)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 517, 22)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 517, 22)) // Repro from #13604 class A { ->A : Symbol(A, Decl(keyofAndIndexedAccess.ts, 503, 59)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 507, 8)) +>A : Symbol(A, Decl(keyofAndIndexedAccess.ts, 517, 59)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 521, 8)) props: T & { foo: string }; ->props : Symbol(A.props, Decl(keyofAndIndexedAccess.ts, 507, 12)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 507, 8)) ->foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 508, 13)) +>props : Symbol(A.props, Decl(keyofAndIndexedAccess.ts, 521, 12)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 521, 8)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 522, 13)) } class B extends A<{ x: number}> { ->B : Symbol(B, Decl(keyofAndIndexedAccess.ts, 509, 1)) ->A : Symbol(A, Decl(keyofAndIndexedAccess.ts, 503, 59)) ->x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 511, 19)) +>B : Symbol(B, Decl(keyofAndIndexedAccess.ts, 523, 1)) +>A : Symbol(A, Decl(keyofAndIndexedAccess.ts, 517, 59)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 525, 19)) f(p: this["props"]) { ->f : Symbol(B.f, Decl(keyofAndIndexedAccess.ts, 511, 33)) ->p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 512, 3)) +>f : Symbol(B.f, Decl(keyofAndIndexedAccess.ts, 525, 33)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 526, 3)) p.x; ->p.x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 511, 19)) ->p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 512, 3)) ->x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 511, 19)) +>p.x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 525, 19)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 526, 3)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 525, 19)) } } // Repro from #13749 class Form { ->Form : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 515, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 519, 11)) +>Form : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 529, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 533, 11)) private childFormFactories: {[K in keyof T]: (v: T[K]) => Form} ->childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 519, 15)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 520, 34)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 519, 11)) ->v : Symbol(v, Decl(keyofAndIndexedAccess.ts, 520, 50)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 519, 11)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 520, 34)) ->Form : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 515, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 519, 11)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 520, 34)) +>childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 533, 15)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 534, 34)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 533, 11)) +>v : Symbol(v, Decl(keyofAndIndexedAccess.ts, 534, 50)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 533, 11)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 534, 34)) +>Form : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 529, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 533, 11)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 534, 34)) public set(prop: K, value: T[K]) { ->set : Symbol(Form.set, Decl(keyofAndIndexedAccess.ts, 520, 73)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 522, 15)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 519, 11)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 522, 34)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 522, 15)) ->value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 522, 42)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 519, 11)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 522, 15)) +>set : Symbol(Form.set, Decl(keyofAndIndexedAccess.ts, 534, 73)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 536, 15)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 533, 11)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 536, 34)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 536, 15)) +>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 536, 42)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 533, 11)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 536, 15)) this.childFormFactories[prop](value) ->this.childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 519, 15)) ->this : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 515, 1)) ->childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 519, 15)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 522, 34)) ->value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 522, 42)) +>this.childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 533, 15)) +>this : Symbol(Form, Decl(keyofAndIndexedAccess.ts, 529, 1)) +>childFormFactories : Symbol(Form.childFormFactories, Decl(keyofAndIndexedAccess.ts, 533, 15)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 536, 34)) +>value : Symbol(value, Decl(keyofAndIndexedAccess.ts, 536, 42)) } } // Repro from #13787 class SampleClass

{ ->SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 525, 1)) ->P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 529, 18)) +>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 539, 1)) +>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 543, 18)) public props: Readonly

; ->props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 529, 22)) +>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 543, 22)) >Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) ->P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 529, 18)) +>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 543, 18)) constructor(props: P) { ->props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 531, 16)) ->P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 529, 18)) +>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 545, 16)) +>P : Symbol(P, Decl(keyofAndIndexedAccess.ts, 543, 18)) this.props = Object.freeze(props); ->this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 529, 22)) ->this : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 525, 1)) ->props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 529, 22)) +>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 543, 22)) +>this : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 539, 1)) +>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 543, 22)) >Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) >freeze : Symbol(ObjectConstructor.freeze, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) ->props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 531, 16)) +>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 545, 16)) } } interface Foo { ->Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 534, 1)) +>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 548, 1)) foo: string; ->foo : Symbol(Foo.foo, Decl(keyofAndIndexedAccess.ts, 536, 15)) +>foo : Symbol(Foo.foo, Decl(keyofAndIndexedAccess.ts, 550, 15)) } declare function merge(obj1: T, obj2: U): T & U; ->merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 538, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 540, 23)) ->U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 540, 25)) ->obj1 : Symbol(obj1, Decl(keyofAndIndexedAccess.ts, 540, 29)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 540, 23)) ->obj2 : Symbol(obj2, Decl(keyofAndIndexedAccess.ts, 540, 37)) ->U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 540, 25)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 540, 23)) ->U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 540, 25)) +>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 552, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 554, 23)) +>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 554, 25)) +>obj1 : Symbol(obj1, Decl(keyofAndIndexedAccess.ts, 554, 29)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 554, 23)) +>obj2 : Symbol(obj2, Decl(keyofAndIndexedAccess.ts, 554, 37)) +>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 554, 25)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 554, 23)) +>U : Symbol(U, Decl(keyofAndIndexedAccess.ts, 554, 25)) class AnotherSampleClass extends SampleClass { ->AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 540, 54)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 542, 25)) ->SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 525, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 542, 25)) ->Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 534, 1)) +>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 554, 54)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 556, 25)) +>SampleClass : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 539, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 556, 25)) +>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 548, 1)) constructor(props: T) { ->props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 543, 16)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 542, 25)) +>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 557, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 556, 25)) const foo: Foo = { foo: "bar" }; ->foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 544, 13)) ->Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 534, 1)) ->foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 544, 26)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 558, 13)) +>Foo : Symbol(Foo, Decl(keyofAndIndexedAccess.ts, 548, 1)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 558, 26)) super(merge(props, foo)); ->super : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 525, 1)) ->merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 538, 1)) ->props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 543, 16)) ->foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 544, 13)) +>super : Symbol(SampleClass, Decl(keyofAndIndexedAccess.ts, 539, 1)) +>merge : Symbol(merge, Decl(keyofAndIndexedAccess.ts, 552, 1)) +>props : Symbol(props, Decl(keyofAndIndexedAccess.ts, 557, 16)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 558, 13)) } public brokenMethod() { ->brokenMethod : Symbol(AnotherSampleClass.brokenMethod, Decl(keyofAndIndexedAccess.ts, 546, 5)) +>brokenMethod : Symbol(AnotherSampleClass.brokenMethod, Decl(keyofAndIndexedAccess.ts, 560, 5)) this.props.foo.concat; >this.props.foo.concat : Symbol(String.concat, Decl(lib.d.ts, --, --)) ->this.props.foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 536, 15)) ->this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 529, 22)) ->this : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 540, 54)) ->props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 529, 22)) ->foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 536, 15)) +>this.props.foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 550, 15)) +>this.props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 543, 22)) +>this : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 554, 54)) +>props : Symbol(SampleClass.props, Decl(keyofAndIndexedAccess.ts, 543, 22)) +>foo : Symbol(foo, Decl(keyofAndIndexedAccess.ts, 550, 15)) >concat : Symbol(String.concat, Decl(lib.d.ts, --, --)) } } new AnotherSampleClass({}); ->AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 540, 54)) +>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 554, 54)) // Positive repro from #17166 function f3>(t: T, k: K, tk: T[K]): void { ->f3 : Symbol(f3, Decl(keyofAndIndexedAccess.ts, 552, 27)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14)) +>f3 : Symbol(f3, Decl(keyofAndIndexedAccess.ts, 566, 27)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 14)) >Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12)) ->t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 51)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12)) ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 56)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 62)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 12)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 569, 51)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 569, 56)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 14)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 569, 62)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 14)) for (let key in t) { ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12)) ->t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 51)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 570, 12)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 569, 51)) key = k // ok, K ==> keyof T ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12)) ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 56)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 570, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 569, 56)) t[key] = tk; // ok, T[K] ==> T[keyof T] ->t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 51)) ->key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12)) ->tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 62)) +>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 569, 51)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 570, 12)) +>tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 569, 62)) } } // # 21185 type Predicates = { ->Predicates : Symbol(Predicates, Decl(keyofAndIndexedAccess.ts, 560, 1)) ->TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16)) +>Predicates : Symbol(Predicates, Decl(keyofAndIndexedAccess.ts, 574, 1)) +>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 577, 16)) [T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T] ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3)) ->TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16)) ->variant : Symbol(variant, Decl(keyofAndIndexedAccess.ts, 564, 30)) ->TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16)) ->TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16)) ->variant : Symbol(variant, Decl(keyofAndIndexedAccess.ts, 564, 30)) ->TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 578, 3)) +>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 577, 16)) +>variant : Symbol(variant, Decl(keyofAndIndexedAccess.ts, 578, 30)) +>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 577, 16)) +>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 577, 16)) +>variant : Symbol(variant, Decl(keyofAndIndexedAccess.ts, 578, 30)) +>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 577, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 578, 3)) } // Repros from #23592 type Example = { [K in keyof T]: T[K]["prop"] }; ->Example : Symbol(Example, Decl(keyofAndIndexedAccess.ts, 565, 1)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 26)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 569, 42)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 63)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 569, 13)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 569, 63)) +>Example : Symbol(Example, Decl(keyofAndIndexedAccess.ts, 579, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 583, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 583, 26)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 583, 13)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 583, 42)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 583, 63)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 583, 13)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 583, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 583, 63)) type Result = Example<{ a: { prop: string }; b: { prop: number } }>; ->Result : Symbol(Result, Decl(keyofAndIndexedAccess.ts, 569, 93)) ->Example : Symbol(Example, Decl(keyofAndIndexedAccess.ts, 565, 1)) ->a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 570, 23)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 570, 28)) ->b : Symbol(b, Decl(keyofAndIndexedAccess.ts, 570, 44)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 570, 49)) +>Result : Symbol(Result, Decl(keyofAndIndexedAccess.ts, 583, 93)) +>Example : Symbol(Example, Decl(keyofAndIndexedAccess.ts, 579, 1)) +>a : Symbol(a, Decl(keyofAndIndexedAccess.ts, 584, 23)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 584, 28)) +>b : Symbol(b, Decl(keyofAndIndexedAccess.ts, 584, 44)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 584, 49)) type Helper2 = { [K in keyof T]: Extract }; ->Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 572, 21)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13)) +>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 584, 68)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 586, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 586, 21)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 586, 13)) >Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 572, 13)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 572, 21)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 572, 51)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 586, 13)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 586, 21)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 586, 51)) type Example2 = { [K in keyof Helper2]: Helper2[K]["prop"] }; ->Example2 : Symbol(Example2, Decl(keyofAndIndexedAccess.ts, 572, 67)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 573, 22)) ->Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14)) ->Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 570, 68)) ->T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 573, 14)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 573, 22)) +>Example2 : Symbol(Example2, Decl(keyofAndIndexedAccess.ts, 586, 67)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 587, 14)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 587, 22)) +>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 584, 68)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 587, 14)) +>Helper2 : Symbol(Helper2, Decl(keyofAndIndexedAccess.ts, 584, 68)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 587, 14)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 587, 22)) type Result2 = Example2<{ 1: { prop: string }; 2: { prop: number } }>; ->Result2 : Symbol(Result2, Decl(keyofAndIndexedAccess.ts, 573, 70)) ->Example2 : Symbol(Example2, Decl(keyofAndIndexedAccess.ts, 572, 67)) ->1 : Symbol(1, Decl(keyofAndIndexedAccess.ts, 574, 25)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 574, 30)) ->2 : Symbol(2, Decl(keyofAndIndexedAccess.ts, 574, 46)) ->prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 574, 51)) +>Result2 : Symbol(Result2, Decl(keyofAndIndexedAccess.ts, 587, 70)) +>Example2 : Symbol(Example2, Decl(keyofAndIndexedAccess.ts, 586, 67)) +>1 : Symbol(1, Decl(keyofAndIndexedAccess.ts, 588, 25)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 588, 30)) +>2 : Symbol(2, Decl(keyofAndIndexedAccess.ts, 588, 46)) +>prop : Symbol(prop, Decl(keyofAndIndexedAccess.ts, 588, 51)) // Repro from #23618 type DBBoolTable = { [k in K]: 0 | 1 } ->DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 574, 70)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 578, 17)) ->k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 578, 40)) ->K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 578, 17)) +>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 588, 70)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 592, 17)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 592, 40)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 592, 17)) enum Flag { ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 578, 56)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 592, 56)) FLAG_1 = "flag_1", ->FLAG_1 : Symbol(Flag.FLAG_1, Decl(keyofAndIndexedAccess.ts, 579, 11)) +>FLAG_1 : Symbol(Flag.FLAG_1, Decl(keyofAndIndexedAccess.ts, 593, 11)) FLAG_2 = "flag_2" ->FLAG_2 : Symbol(Flag.FLAG_2, Decl(keyofAndIndexedAccess.ts, 580, 22)) +>FLAG_2 : Symbol(Flag.FLAG_2, Decl(keyofAndIndexedAccess.ts, 594, 22)) } type SimpleDBRecord = { staticField: number } & DBBoolTable ->SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 582, 1)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 584, 20)) ->staticField : Symbol(staticField, Decl(keyofAndIndexedAccess.ts, 584, 44)) ->DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 574, 70)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 584, 20)) +>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 596, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 598, 20)) +>staticField : Symbol(staticField, Decl(keyofAndIndexedAccess.ts, 598, 44)) +>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 588, 70)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 598, 20)) function getFlagsFromSimpleRecord(record: SimpleDBRecord, flags: Flag[]) { ->getFlagsFromSimpleRecord : Symbol(getFlagsFromSimpleRecord, Decl(keyofAndIndexedAccess.ts, 584, 86)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 585, 34)) ->record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 585, 55)) ->SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 582, 1)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 585, 34)) ->flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 585, 84)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 585, 34)) +>getFlagsFromSimpleRecord : Symbol(getFlagsFromSimpleRecord, Decl(keyofAndIndexedAccess.ts, 598, 86)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 599, 34)) +>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 599, 55)) +>SimpleDBRecord : Symbol(SimpleDBRecord, Decl(keyofAndIndexedAccess.ts, 596, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 599, 34)) +>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 599, 84)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 599, 34)) return record[flags[0]]; ->record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 585, 55)) ->flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 585, 84)) +>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 599, 55)) +>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 599, 84)) } type DynamicDBRecord = ({ dynamicField: number } | { dynamicField: string }) & DBBoolTable ->DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 587, 1)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 589, 21)) ->dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 589, 46)) ->dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 589, 73)) ->DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 574, 70)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 589, 21)) +>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 601, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 603, 21)) +>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 603, 46)) +>dynamicField : Symbol(dynamicField, Decl(keyofAndIndexedAccess.ts, 603, 73)) +>DBBoolTable : Symbol(DBBoolTable, Decl(keyofAndIndexedAccess.ts, 588, 70)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 603, 21)) function getFlagsFromDynamicRecord(record: DynamicDBRecord, flags: Flag[]) { ->getFlagsFromDynamicRecord : Symbol(getFlagsFromDynamicRecord, Decl(keyofAndIndexedAccess.ts, 589, 117)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 590, 35)) ->record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 590, 56)) ->DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 587, 1)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 590, 35)) ->flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 590, 86)) ->Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 590, 35)) +>getFlagsFromDynamicRecord : Symbol(getFlagsFromDynamicRecord, Decl(keyofAndIndexedAccess.ts, 603, 117)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 604, 35)) +>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 604, 56)) +>DynamicDBRecord : Symbol(DynamicDBRecord, Decl(keyofAndIndexedAccess.ts, 601, 1)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 604, 35)) +>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 604, 86)) +>Flag : Symbol(Flag, Decl(keyofAndIndexedAccess.ts, 604, 35)) return record[flags[0]]; ->record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 590, 56)) ->flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 590, 86)) +>record : Symbol(record, Decl(keyofAndIndexedAccess.ts, 604, 56)) +>flags : Symbol(flags, Decl(keyofAndIndexedAccess.ts, 604, 86)) +} + +// Repro from #21368 + +interface I { +>I : Symbol(I, Decl(keyofAndIndexedAccess.ts, 606, 1)) + + foo: string; +>foo : Symbol(I.foo, Decl(keyofAndIndexedAccess.ts, 610, 13)) +} + +declare function take(p: T): void; +>take : Symbol(take, Decl(keyofAndIndexedAccess.ts, 612, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 614, 22)) +>p : Symbol(p, Decl(keyofAndIndexedAccess.ts, 614, 25)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 614, 22)) + +function fn(o: T, k: K) { +>fn : Symbol(fn, Decl(keyofAndIndexedAccess.ts, 614, 37)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 616, 12)) +>I : Symbol(I, Decl(keyofAndIndexedAccess.ts, 606, 1)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 616, 24)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 616, 12)) +>o : Symbol(o, Decl(keyofAndIndexedAccess.ts, 616, 44)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 616, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 616, 49)) +>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 616, 24)) + + take<{} | null | undefined>(o[k]); +>take : Symbol(take, Decl(keyofAndIndexedAccess.ts, 612, 1)) +>o : Symbol(o, Decl(keyofAndIndexedAccess.ts, 616, 44)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 616, 49)) + + take(o[k]); +>take : Symbol(take, Decl(keyofAndIndexedAccess.ts, 612, 1)) +>o : Symbol(o, Decl(keyofAndIndexedAccess.ts, 616, 44)) +>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 616, 49)) +} + +// Repro from #23133 + +class Unbounded { +>Unbounded : Symbol(Unbounded, Decl(keyofAndIndexedAccess.ts, 619, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 623, 16)) + + foo(x: T[keyof T]) { +>foo : Symbol(Unbounded.foo, Decl(keyofAndIndexedAccess.ts, 623, 20)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 624, 8)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 623, 16)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 623, 16)) + + let y: {} | undefined | null = x; +>y : Symbol(y, Decl(keyofAndIndexedAccess.ts, 625, 11)) +>x : Symbol(x, Decl(keyofAndIndexedAccess.ts, 624, 8)) + } } diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index 51b91526fdb..0d6a350bd3c 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -1497,6 +1497,73 @@ function f90(x1: S2[keyof S2], x2: T[keyof S2] >length : number } +function f91(x: T, y: T[keyof T], z: T[K]) { +>f91 : (x: T, y: T[keyof T], z: T[K]) => void +>T : T +>K : K +>T : T +>x : T +>T : T +>y : T[keyof T] +>T : T +>T : T +>z : T[K] +>T : T +>K : K + + let a: {}; +>a : {} + + a = x; +>a = x : T +>a : {} +>x : T + + a = y; +>a = y : T[keyof T] +>a : {} +>y : T[keyof T] + + a = z; +>a = z : T[K] +>a : {} +>z : T[K] +} + +function f92(x: T, y: T[keyof T], z: T[K]) { +>f92 : (x: T, y: T[keyof T], z: T[K]) => void +>T : T +>K : K +>T : T +>x : T +>T : T +>y : T[keyof T] +>T : T +>T : T +>z : T[K] +>T : T +>K : K + + let a: {} | null | undefined; +>a : {} | null | undefined +>null : null + + a = x; +>a = x : T +>a : {} | null | undefined +>x : T + + a = y; +>a = y : T[keyof T] +>a : {} | null | undefined +>y : T[keyof T] + + a = z; +>a = z : T[K] +>a : {} | null | undefined +>z : T[K] +} + // Repros from #12011 class Base { @@ -2463,3 +2530,64 @@ function getFlagsFromDynamicRecord(record: DynamicDBRecord< >0 : 0 } +// Repro from #21368 + +interface I { +>I : I + + foo: string; +>foo : string +} + +declare function take(p: T): void; +>take : (p: T) => void +>T : T +>p : T +>T : T + +function fn(o: T, k: K) { +>fn : (o: T, k: K) => void +>T : T +>I : I +>K : K +>T : T +>o : T +>T : T +>k : K +>K : K + + take<{} | null | undefined>(o[k]); +>take<{} | null | undefined>(o[k]) : void +>take : (p: T) => void +>null : null +>o[k] : T[K] +>o : T +>k : K + + take(o[k]); +>take(o[k]) : void +>take : (p: T) => void +>o[k] : T[K] +>o : T +>k : K +} + +// Repro from #23133 + +class Unbounded { +>Unbounded : Unbounded +>T : T + + foo(x: T[keyof T]) { +>foo : (x: T[keyof T]) => void +>x : T[keyof T] +>T : T +>T : T + + let y: {} | undefined | null = x; +>y : {} | null | undefined +>null : null +>x : T[keyof T] + } +} +